2016-12-02 28 views
1

我想將NVARCHAR2類型的所有列更新爲我的數據庫中的一些隨機字符串。我遍歷nvarchar2類型的數據庫中的所有列,併爲每列執行更新語句。Oracle:使用動態查詢更新多個列

for i in (
    select 
     table_name, 
     column_name 
    from 
     user_tab_columns 
    where 
     data_type = 'NVARCHAR2' 
    ) loop 
execute immediate 
    'update ' || i.table_name || 'set ' || i.column_name || 
    ' = DBMS_RANDOM.STRING(''X'', length('|| i.column_name ||')) 
    where ' || i.column_name || ' is not null'; 

相反運行的更新語句類型NVARCHAR2的每一列的,我想與效率的一個更新語句更新特定表的所有nvarchar列(即每1臺一個update語句) 。爲此,我嘗試將表中的所有nvarchar列批量收集到臨時存儲中。但是,我堅持寫這個動態更新語句。你能幫我解決這個問題嗎?提前致謝!

+0

具有特定表的所有列的內部循環,並追加列進行更新。這是你必須反覆運行還是一次運行?如果有一次,只需編寫一個腳本來發出更新的另一個腳本,然後運行第二個腳本。 – OldProgrammer

+0

將列添加到'SET'是我卡住的地方。在集合中寫入選擇是不可能的。你有什麼想法如何追加? – rav

+0

用字符串創建更新,附加到該字符串,然後立即對字符串執行。 – OldProgrammer

回答

1

請試試這個:

DECLARE 
    CURSOR CUR IS 
     SELECT 
      TABLE_NAME, 
      LISTAGG(COLUMN_NAME||' = DBMS_RANDOM.STRING(''X'', length(NVL('|| 
      COLUMN_NAME ||',''A''))',', ') 
      WITHIN GROUP (ORDER BY COLUMN_ID) COLUMN_NAME 
     FROM DBA_TAB_COLUMNS 
     WHERE DATA_TYPE = 'NVARCHAR2' 
     GROUP BY TABLE_NAME; 
    TYPE TAB IS TABLE OF CUR%ROWTYPE INDEX BY PLS_INTEGER; 
    T TAB; 
    S VARCHAR2(4000); 
BEGIN 
    OPEN CUR; 
    LOOP 
     FETCH CUR BULK COLLECT INTO T LIMIT 1000; 
     EXIT WHEN T.COUNT = 0; 
     FOR i IN 1..T.COUNT LOOP 
      S := 'UPDATE ' || T(i).TABLE_NAME || ' SET ' || T(i).COLUMN_NAME; 
      EXECUTE IMMEDIATE S; 
     END LOOP; 
    END LOOP; 
    COMMIT; 
END; 
/
+0

@rav NVL部分負責處理多列更新中的空值。如果它不適合你,那麼你必須一個接一個地做。沒有別的去。 – GurV

+0

感謝您的努力。不勝感激! – rav

+0

'''A''))'' - >''''')))''。請添加'哪裏colname非空'過濾器的模擬。 –

1

我認爲這將做到這一點。但正如我在評論中所說的,你需要驗證語法,因爲我沒有一個Oracle實例來測試它。

for i in (
    select table_name, 
      'update || i.table_name || set ' || 
      listagg(column_name || '= NLV(' || column_name || ', ' 
       || 'DBMS_RANDOM.STRING(''X'', length('|| column_name ||')))' 
       || ';' 
      ) WITHIN GROUP (ORDER BY column_name) as updCommand 
    from user_tab_columns 
    where DATA_TYPE = 'NVARCHAR2' 
    group by table_name 
) loop 

    execute immediate i.updCommand; 

end loop; 

如果您發現任何錯誤,請在評論中告訴我,以便我可以修復它。

+0

'組內沒有 –

+0

錯誤報告 - SQL錯誤:ORA-02000 :缺少WITHIN關鍵字 02000. 00000 - 「缺少%s關鍵字」 – rav

+0

@rav修正了它,請現在就試試。 –

2

你可以試試這個。但是,根據您的表格,它可能不是最快的解決方案。

for aTable in (
    select table_name, 
     listagg(column_name||' = nvl2('||column_name||', DBMS_RANDOM.STRING(''XX'', length('||column_name||')), NULL)') WITHIN GROUP (ORDER BY column_name) as upd, 
     listagg(column_name) WITHIN GROUP (ORDER BY column_name) as con 
    from user_tab_columns 
    where DATA_TYPE = 'NVARCHAR2' 
    group by table_name 
) loop 

    execute immediate 
     'UPDATE '||aTable.table_name || 
     ' SET '||aTable.upd || 
     ' WHERE COALESCE('||aTable.con||') IS NOT NULL'; 

end loop; 

最終的更新(與DBMS_OUTPUT.PUT_LINE(..)驗證)應該是這樣的:

UPDATE MY_TABLE SET 
    COL_A = nvl2(COL_A, DBMS_RANDOM.STRING('XX', length(COL_A)), NULL), 
    COL_B = nvl2(COL_B, DBMS_RANDOM.STRING('XX', length(COL_B)), NULL) 
WHERE COALESCE(COL_A, COL_B) IS NOT NULL;