簡體   English   中英

如何將bash變量傳遞給sqlplus,然后將該輸出傳遞給另一個變量

[英]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實例,但是我看到兩種方法可以做到這一點:

  1. 通過SQL * Plus建立許多連接
    1. 首先,檢索pdb_name
    2. 其次,設置容器並刪除審核。
  2. 使用單個SQL * Plus,但使用兩個命名管道
    1. 一個發送生成的SQL命令
    2. 秒讀SQL * Plus輸出

作為替代方式,我應該使用一種“真正的”編程語言(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM