Oracle:使用动态列名更新表

时间:2016-11-10 16:59:19

标签: oracle oracle11g oracle-sqldeveloper dynamic-columns dynamicquery

我正在使用Oracle 11g。我的表包括name和l_name(name列的小写)之类的列。我试图遍历表空间中的所有列,将l_列设置为各自大写列的小写。这是我试过的:

for i in (select table_name from user_tables) loop
    SELECT SUBSTR(column_name,3) bulk collect into my_temp_storage FROM user_tab_columns WHERE table_name = i.table_name and column_name like 'L\_%' escape '\';
    for j in (select column_name from user_tab_columns where table_name = i.table_name) loop
        for k in 1..my_temp_storage.count
        loop
            if(j.column_name like 'L\_%' escape '\' and SUBSTR(j.column_name,3) = my_temp_storage(k)) then
                DBMS_OUTPUT.PUT_LINE( 'update ' || i.table_name || ' set ' || j.column_name || ' = LOWER(' ||my_temp_storage(k)|| ') where ' || j.column_name || ' is not null');
                execute immediate 'update ' || i.table_name || ' set ' || j.column_name || ' = LOWER(' ||my_temp_storage(k)|| ') where ' || j.column_name || ' is not null';
            end if;
        end loop;
    end loop;
end loop;

我在my_temp_storage中以大写形式存储列的所有名称,并使用my_temp_storage中列的LOWER值更新表。这给了我一个错误说:

Error report -
ORA-00900: invalid SQL statement
ORA-06512: at line 8
00900. 00000 -  "invalid SQL statement"
*Cause:    
*Action: 

但DBMS输出似乎很好:

`update EMPLOYEE set L_NAME = LOWER(NAME) where L_NAME is not null` 

你能用我的方式或任何其他方式来帮助我吗?

1 个答案:

答案 0 :(得分:1)

该计划当然可以简化:

begin
    for i in (select table_name, column_name from user_tab_columns 
              where column_name like 'L\_%' escape '\') 
    loop
        l_sql := 'update ' || i.table_name || ' set ' || i.column_name 
                  || ' = LOWER(' ||substr(i.columm_name,3)
                  || ') where ' || i.column_name || ' is not null';
        execute immediate l_sql;
    end loop;          
end;

虽然这似乎是一个奇怪的数据库设计。您是否考虑过虚拟列和/或基于函数的索引,而不是手动维护的列?