2016-12-02 53 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;