[英]How to pass a bash variable to sqlplus and then pass that output to another variable
因此,我要做的是清除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 $表?
我手頭沒有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;
/
我不斷收到的錯誤是
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的標准輸入,然后將其寫入sqlplus的輸出。 bash絕不挑選sqlplus輸出的某些行並將其放入shell變量中。
實際上,在調用sqlplus之前,嘗試將echo $ALTER
添加到bash腳本中。 您很可能會發現輸出為
alter session set container=select pdb_name from dba_pdbs where pdb_name != 'PDB$SEED';
如果是這樣,那么bash在開始sqlplus
之前就已經完成了您不需要的替換。
您似乎希望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
語句,因為我想確保刪除來自“正確” PDB的數據。 我對此使用PL / SQL的擔心是,PL / SQL編譯器將確定在解析該塊時要從哪個表中刪除該表,該表將在運行該塊之前,因此在執行alter session
語句以更改該表之前PDB。 但是,我對Oracle 12c中的PDB和CDB不夠了解,無法說出這是一個真正的問題還是毫無根據的廢話。
我無權訪問可插拔的Oracle 12c數據庫來對此類數據庫進行運行,因此我無法告訴您此腳本是否有效。 如果沒有,希望它可以使您知道去哪里。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.