【问题标题】:Oracle: update table using dynamic column namesOracle:使用动态列名更新表
【发布时间】:2016-11-10 16:59:19
【问题描述】:

我正在使用 Oracle 11g。我的表包括名称和 l_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` 

你能帮我看看我做的方式或其他可以做的方式吗?

【问题讨论】:

  • 这是我工作表上唯一的内容,第 8 行包含“立即执行”语句
  • 您周围没有beginend?还有my_temp_storage的声明?
  • 您是否有任何以保留字或关键字命名的表或列,和/或带引号的标识符?如果你在执行立即注释掉的情况下运行它会发生什么?
  • 对不起。我没有正确理解您的第一条评论。我以为你是在上面发布的代码的上下文中说话的。我确实拥有所有这些东西,但我只是发布了我的逻辑部分。即使这样,错误也会显示在执行语句的行中!
  • 正如我所发布的,dbms 输出运行良好。如果我注释执行行,所有查询都将打印在输出中

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


【解决方案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;

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

【讨论】:

  • 我一开始也尝试过类似的东西。但是,LOWER('||substr(i.columm_name,3)) 从同一列(即 L_ 列)返回子字符串。
  • 它是对列的 name 的子串而不是它的值,所以没关系?
  • 这是有效的。非常感谢。我之前尝试过的方法是:LOWER( substr(' ||i.columm_name|| ',3) 它实际上给出了同一列的小写值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 2022-07-05
  • 2021-06-22
  • 1970-01-01
相关资源
最近更新 更多