1、Oracle数据库内调用单个shell变量
lv_table=T1
sqlplus / as sysdba <<EOF #<<EOF必须紧跟在上述命令后以一个空格分开
select count(*) from $lv_table;
EOF
[oracle@lissen db_sh]$ ./exec_stats.sh
SQL*Plus: Release 19.0.0.0.0 - Production on Sat Jun 1 23:15:00 2019
Version 19.2.0.0.0
Copyright (c) 1982, 2018, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.2.0.0.0
SYS@lissen>
COUNT(*)
----------
2
SYS@lissen>Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.2.0.0.0
2、Oracle数据库读取多个shell变量
命令输入
<<EOF
EOF
[oracle@lissen db_sh]$ cat 1.sh
<<COMMENT
lv_table=T1
sqlplus / as sysdba <<EOF
select count(*) from $lv_table;
EOF
COMMENT
for i in T1 T2
do
sqlplus / as sysdba <<EOF
select count(*) from $i;
EOF
done
[oracle@lissen db_sh]$ ./1.sh
SQL*Plus: Release 19.0.0.0.0 - Production on Sat Jun 1 23:25:22 2019
Version 19.2.0.0.0
Copyright (c) 1982, 2018, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.2.0.0.0
SYS@lissen>
COUNT(*)
----------
2
SYS@lissen>Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.2.0.0.0
SQL*Plus: Release 19.0.0.0.0 - Production on Sat Jun 1 23:25:22 2019
Version 19.2.0.0.0
Copyright (c) 1982, 2018, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.2.0.0.0
SYS@lissen>
COUNT(*)
----------
32
SYS@lissen>Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.2.0.0.0
#!/bin/bash
lv_table=T1
lv_table2=T2
for i in $lv_table $lv_table2
do
sqlplus -S scott/scott@TNS_PDB01 <<EOF
select count(*) from $i;
exit;
EOF
done
3、shell使用SQLPLUS –S进行查询
-S 静默查询
[oracle@lissen-node1 test_shell]$ sqlplus -S / as sysdba;
select count(*) from scott.t1;
COUNT(*)
----------
14
#取消查询输出的标题
set heading off;
select count(*) from scott.t1;
14
set verify off;
select count(*) from scott.t1;
14
#不设置页大小
set pagesize 0;
select count(*) from scott.t1;
14
set echo off;
select count(*) from scott.t;
select count(*) from scott.t1;
14
4、从数据库中读取查询结果并保存在SHELL变量中
#!/bin/bash
#resultCount=`sqlplus -S scott/scott@TNS_PDB01 <<EOF
# set heading off;
# set feedback off;
# set pagesize 0;
# select count(*) from t1;
# exit;
#EOF`
#echo $resultCount
#如果使用$(命令)方式”)”必须处于当单独一行
resultCount=$(sqlplus -S scott/scott@TNS_PDB01 <<EOF
set heading off;
set feedback off;
set pagesize 0;
select count(*) from t1;
EOF
)
echo $resultCount
5、读取数据库内数据到shell变量并用for循环输出
set heading off 去掉表头
set feedback off 去掉数据下方的空白行
set pagesize 0 去掉数据上方的空白行
[oracle@lissen db_sh]$ cat 2.sh
#!/bin/bash
for i in `sqlplus -S / as sysdba <<EOF
set heading off;
set pagesize 0;
set feedback off;
set verify off;
set echo off;
select id from t1;
EOF`
do
echo $i
done
[oracle@lissen db_sh]$ ./2.sh
1
2
3
4
6、使用系统文件内容做为shell变量查询数据库中表数据
[oracle@lissen db_sh]$ cat /home/oracle/db_sh/exec_table.txt
T1
T2
T3
[oracle@lissen db_sh]$ bash -n exec_stats.sh
[oracle@lissen db_sh]$ cat exec_stats.sh
#!/bin/bash
lv_table=$(cat /home/oracle/db_sh/exec_table.txt)
for i in $lv_table
do
sqlplus -S / as sysdba <<EOF
host echo "Begin select data from $i";
select count(*) from $i;
host echo "End select data from $i";
EOF
done
[oracle@lissen db_sh]$ ./exec_stats.sh
Begin select data from T1
COUNT(*)
----------
4
End select data from T1
Begin select data from T2
COUNT(*)
----------
32
End select data from T2
Begin select data from T3
COUNT(*)
----------
4
End select data from T3
7、 抓取Oracle数据库内的SYS用户中10天内未收集统计信息的表,并收集其统计信息
抓取Oracle数据库内的SYS用户中10天内未收集统计信息的表并保存到OS文件上
[oracle@lissen db_sh]$ cat 3.sh
#!/bin/bash
#select table_name from dba_tab_statistics where owner = 'SYS' and sysdate - last_analyzed > 10;
lv_file=`sqlplus -S / as sysdba <<EOF
set heading off;
set pagesize 0;
set feedback off;
select table_name from dba_tab_statistics where owner = 'SYS' and sysdate - last_analyzed > 10;
exit;
EOF`
<<COMMENT
for i in $lv_file
do
echo $i
done
COMMENT
for i in $lv_file
do
echo $i
done >> /home/oracle/db_sh/sys_table.txt
收集SYS用户10天内未收集统计信息的表的统计信息
查询SCOTT用户下1分钟内未收集统计或者重未收集过统计信息
SCOTT@dgpri>select owner,table_name,last_analyzed from dba_tab_statistics where owner = 'SCOTT' and (sysdate - last_analyzed > 1/(1*24*60) or last_analyzed is null);
OWNER TABLE_NAME LAST_ANALYZED
---------- --------------- -------------------
SCOTT DEPT 2019-06-17 10:50:03
SCOTT EMP 2019-06-17 10:50:04
SCOTT BONUS 2019-06-17 10:50:05
SCOTT SALGRADE 2019-06-17 10:50:05
SCOTT T1
查询SCOTT用户下10天内未收集统计或者重未收集过统计信息
SCOTT@dgpri>select owner,table_name,last_analyzed from dba_tab_statistics where owner = 'SCOTT' and (sysdate - last_analyzed > 10 or last_analyzed is null);
OWNER TABLE_NAME LAST_ANALYZED
---------- --------------- -------------------
SCOTT T1
合并起来脚本为
lv_file=`sqlplus -S / as sysdba <<EOF
set heading off;
set pagesize 0;
set feedback off;
select table_name from dba_tab_statistics where owner = 'SYS' and sysdate - last_analyzed > 10;
exit;
EOF`
for i in $lv_file
do
sqlplus -S / as sysdba <<EOF
host echo "Begin gather $i statistics!";
exec dbms_stats.gather_table_stats(ownname => 'SYS',tabname => '$i',estimate_percent => 100,method_opt => 'FOR ALL COLUMNS SIZE 1',cascade => true,no_invalidate => false);
host echo "End gather $i statistics!";
EOF
done
8、 收集N天未收集统计信息的表并收集其统计信息
可以使用如下SQL查询来做测试
SYS@TNS_PDB01>select owner,table_name from dba_tab_statistics where table_name like 'T_';
OWNER TABLE_NAME
---------- ---------------
SCOTT T1
SCOTT T3
SCOTT T2
SCOTT T4
SYS T5
SYS T6
6 rows selected.
SYS@TNS_PDB01>select owner,table_name,last_analyzed from dba_tab_statistics where table_name like 'T_';
OWNER TABLE_NAME LAST_ANALYZED
---------- --------------- -------------------
SCOTT T1 2020-01-13 01:27:37
SCOTT T3 2020-01-13 01:27:37
SCOTT T2 2020-01-13 01:27:37
SCOTT T4 2020-01-13 01:27:38
SYS T5 2020-01-13 01:27:38
SYS T6 2020-01-13 01:27:39
相关查询系统统计信息收集语句
10分钟内收集过的统计信息
SCOTT@GGG1>select owner,table_name,last_analyzed from dba_tab_statistics where owner = 'SCOTT' and sysdate - last_analyzed < 10/(1*24*60) or last_analyzed is null;
OWNER TABLE_NAME LAST_ANALYZED
---------- --------------- -------------------
SCOTT T1 2019-12-12 15:07:18
last_analyzed is null //表示从未收集过统计信息的情况
10天内未收集过的统计信息
select owner,table_name,last_analyzed from dba_tab_statistics where owner = 'SCOTT' and sysdate - last_analyzed > 10 or last_analyzed is null;
收集10天内未收集过的统计信息的OWNER和TABLE_NAME脚本
#!/bin/bash
#默认情况下读取数据为空格修改默认变量IFS为换行符$’\n’
old_IFS=$IFS
IFS=$'\n'
lv_1=$(sqlplus -S / as sysdba <<EOF
set heading off;
set pagesize 0;
set feedback off;
column table_name format a35;
column owner format a20;
select owner,table_name from dba_tab_statistics where sysdate - last_analyzed > 10 and table_name not like 'X$%' order by last_analyzed ;
EOF
)
for i in $lv_1
do
echo $i
done > /home/oracle/test_sh/tab1.txt
IFS=$old_IFS
合并后脚本
[oracle@lissen db_sh]$ cat gather_stats.sh
#!/bin/bash
#指定未收集统计信息的表到一个文件
file_name=/home/oracle/db_sh/tab.txt
old_IFS=$IFS
#指定换行符为读取一行的结尾默认为空格
IFS=$'\n'
if [ ! -f $file_name ];then
touch $file_name
else
rm -rf $file_name
touch $file_name
fi
#使用变量lv_table收集从Oracle数据库返回的表和owner
lv_table=`sqlplus -S sys/oracle@TNS_PDB01 as sysdba <<EOF
#屏蔽select语句
set pagesize 0;
#屏蔽受影响的行数
set feedback off;
column table_name format a35;
#SQL语句根据实际情况进行修改,这里做测试只抓起1天内未收集信息的表的前10行
select distinct table_name,owner from dba_tab_statistics where ((sysdate - last_analyzed) > 1 or last_analyzed is null) and table_name not like 'X$%' and table_name not like 'WRI$%' and rownum < 11;
EOF`
#遍历变量lv_table并将结果重定向到文件
for i in $lv_table
do
echo $i
done > $file_name
#逐行读取文件$file_name中table_name和owner,以/n为分隔符号
while read line
do
for i in $line
do
#echo "-----------------------"
#echo -n "$counter: "
#echo $i | awk '{print $2}'
#echo
#echo -n "$counter: "
#echo $i | awk '{print $1}'
#let counter++
sqlplus -S sys/oracle@TNS_PDB01 as sysdba <<EOF
host echo "Begin gather `echo $i | awk '{print $2}'`'s `echo $i | awk '{print $1}'` stats!";
exec dbms_stats.gather_table_stats(ownname => '`echo $i | awk '{print $2}'`',tabname => '`echo $i | awk '{print $1}'`',estimate_percent => 100,cascade => true);
host echo "End gather `echo $i | awk '{print $2}'`'s `echo $i | awk '{print $1}'` stats!";
EOF
done
done < $file_name
IFS=$old_IFS
#!/bin/bash
old_IFS=$IFS
file_name=/home/oracle/test_sh/tab1.txt
IFS=$'\n'
lv_1=$(sqlplus -S / as sysdba <<EOF
set heading off;
set pagesize 0;
set feedback off;
column table_name format a35;
column owner format a20;
select owner,table_name from dba_tab_statistics where sysdate - last_analyzed > 10 and table_name not like 'X$%' order by last_analyzed ;
EOF
)
for i in $lv_1
do
echo $i
done 1> $file_name
while read line
do
for i in $line
do
lv_owner=$(echo $i | awk '{print $1}')
lv_table=$(echo $i | awk '{print $2}')
sqlplus -S / as sysdba <<EOF
host echo "Begin exec $lv_owner.$lv_table's statistics.";
exec dbms_stats.gather_table_stats(ownname => '$lv_owner',tabname => '$lv_table',estimate_percent => 100,method_opt => 'FOR ALL COLUMNS SIZE 1',cascade => true,no_invalidate => false);
host echo "End exec $lv_owner.$lv_table's statistics.";
EOF
done
done 0< $file_name
IFS=$old_IFS