因此,我要做的是清除Oracle数据库中PDB的审核日志。 PDB的名称每次都可以不同,所以我不能将tnsnames直接用于sqlplus进入PDB来执行此操作。我将命令传递给bash,然后将它们传递给SQLPLUS命令。除了一个之外,这些工作中的每个都工作,我似乎无法弄清楚如何让它工作。
我的代码是
AUDIT="DELETE FROM SYS.AUD$ WHERE NTIMESTAMP# < sysdate-30;"
FINDPDB="select pdb_name from dba_pdbs where pdb_name != 'PDB\$SEED';"
ALTER="alter session set container=$FINDPDB;"
sqlplus -S /nolog <<EOF1
connect / as sysdba
set echo off feedback off head off pages 0
set serveroutput on
$FINDPDB
$ALTER
$AUDIT
exit;
EOF1
我一直得到的错误是
alter session set container=select pdb_name from dba_pdbs where pdb_name != 'PDB$SEED';
*
ERROR at line 1:
ORA-65015: missing or invalid container name
这告诉我它没有将select语句的输出传递给$ FINDPDB,而是实际的select语句本身。
有没有办法可以将此值传递给ALTER变量并让它改变会话并清除sys.aud $表?
答案 0 :(得分:0)
我手头没有Oracle实例,但我认为有两种方法可以做到这一点:
pdb_name
。作为替代方式,我应该使用“真正的”编程语言(Ruby,Python,JavaScript),它们更专用于处理从数据库读取的数据。
编辑:经过一些搜索,可以在PL / SQL中完成
DECLARE
v_pdb_name VARCHAR2(255);
BEGIN
SELECT pdb_name INTO v_pdb_name FROM dba_pdbs WHERE pdb_name != 'PDB\$SEED';
EXECUTE IMMEDIATE 'ALTER SESSION SET container='||v_pdb_name;
DELETE FROM sys.aud$ WHERE ntimestamp# < sysdate-30;
END;
/
答案 1 :(得分:0)
我一直得到的错误是
alter session set container=select pdb_name from dba_pdbs where pdb_name != 'PDB$SEED'; * ERROR at line 1: ORA-65015: missing or invalid container name
这告诉我它没有将select语句的输出传递给$ FINDPDB,而是实际的select语句本身。
我不明白为什么你希望这会将SELECT
查询的输出传递给$FINDPDB
。你将一个很长的字符串放在一起,bash传递给sqlplus的标准输入,然后写入stdout来自sqlplus的输出。在任何时候,bash都不会选择sqlplus输出的某些行并将它们放入shell变量中。
实际上,在调用sqlplus之前,请尝试将echo $ALTER
添加到bash脚本中。你很可能会发现输出是
alter session set container=select pdb_name from dba_pdbs where pdb_name != 'PDB$SEED';
如果是这样,那么在你开始sqlplus
之前,bash已经完成了你不想要的替换。
你似乎希望bash和sqlplus有一些来回的对话。我会放弃这种方法。我没有尝试将PDB名称放入shell变量,而是将其放入sqlplus替换变量中。我会尝试类似以下内容(未经测试):
sqlplus -S /nolog <<"EOF1"
connect / as sysdba
set echo off feedback off head off pages 0
set serveroutput on
column pdb_name new_value pdb
select pdb_name from dba_pdbs where pdb_name != 'PDB\$SEED';
alter session set container = &pdb.;
delete from sys.aud$ where ntimestamp# < sysdate - 30;
exit;
EOF1
我们使用column pdb_name new_value pdb
将替换变量pdb
设置为从名为pdb_name
的列中选择的下一个值。然后,我们运行select
查询以获取PDB名称,并将其存储在pdb
中。一旦我们在替换变量中获得了这个值,我们就可以发出alter session
语句来更改PDB,最后发出delete
语句来删除PDB中的数据。
我很想避免使用PL / SQL块,正如另一个答案中所建议的那样。我希望在PDB更改后解析delete
语句,因为我希望确保来自&#39;更正的数据&#39; PDB正在删除。我对使用PL / SQL的关注是PL / SQL编译器将确定在解析块时要删除哪个表,这将在它运行块之前,因此在它执行alter session
语句之前改变PDB。但是,我不太了解Oracle 12c中的PDB和CDB,足以说明这是真正的问题还是毫无根据的废话。
我无法访问可插拔的Oracle 12c数据库以运行此类操作,因此我无法告诉您此脚本是否有效。如果没有,希望它应该让你知道去哪里。