-1

我正在尝试为那些违反给定阈值的表空间获取表空间总空间。当我在输出中获得多个表空间时,我将它们拆分,然后在数组上运行 for 循环。现在我需要为每个 i 获取字节,但它是第一次出现的唯一打印值。我应该如何附加所有值?请检查以下代码:

output1=`sqlplus -s username/password as sysbackup <<END1
set linesize 200
set head off
select tablespace_name||',' from dba_tablespace_usage_metrics where used_percent > 50;
exit;
END1`

IFS=', ' read -r -a array <<< $output1

for val in "${array[@]}"
do
output2=`sqlplus -s username/password as sysbackup <<END2
set serveroutput on;
set linesize 200
set head off
spool test.txt
SELECT TABLESPACE_NAME, ROUND (SUM (BYTES) / 1048576) FROM DBA_DATA_FILES WHERE TABLESPACE_NAME = '${array[val]}' GROUP BY TABLESPACE_NAME;
spool off;
@test.txt
exit;
END2`
done

@test.sql 应该打印:

SYSAUX 2048
SYSTEM 4027

但它唯一的印刷品:

SYSAUX 2048
4

1 回答 1

2

您的代码目前没有从循环中打印任何内容;如果您$output2在循环之后打印,那么您会看到该值一次;如果您在循环中执行此操作,那么您会多次看到它,并且具有相同的值。每个输出还会加上一个 SP-0734 错误,您可能会对此进行抑制。

当您写信时,test.txt您会将查询结果dba_data_files放入该文件中;并且$val具有数组中的值而不是索引,因此${array[val]}并不意味着您可能认为的那样,并且始终为您提供数组中的第一个元素;因此,每次循环时,您都会从test.txt.

然后你执行它,它得到一个错误。但是初始查询和错误都被捕获到output2- 就像您test.txt手动运行时看到的一样。并且每次都会被覆盖。因此,如果您在循环中处理/显示它,您会看到重复的相同结果;如果您在循环之后运行它(根据您的描述,这似乎是您正在做的事情),那么您会看到它一次。

如果您真的想每次在循环周围附加输出,您可以这样做:

output2=${output2}`sqlplus -s username/password as sysbackup <<END2
...
END2`

或者:

output2+=`sqlplus -s username/password as sysbackup <<END2
...
END2`

但是您需要清理两个查询产生的输出,然后可能需要在该连接中包含换行符。

这作为单个查询会简单得多,它只是直接输出而不是变量:

sqlplus -s username/password as sysbackup <<END1

set pagesize 0
set linesize 200
set feedback off

SELECT TABLESPACE_NAME, ROUND (SUM (BYTES) / 1048576)
FROM DBA_DATA_FILES
WHERE TABLESPACE_NAME IN (
  select tablespace_name
  from dba_tablespace_usage_metrics
  where used_percent > 50
)
GROUP BY TABLESPACE_NAME
ORDER BY TABLESPACE_NAME;

END1

如果您不希望列对齐,则连接名称和大小值:

SELECT TABLESPACE_NAME || ' ' || ROUND (SUM (BYTES) / 1048576)
于 2021-06-30T15:37:25.087 回答