0

我正在使用Oracle 11g。我的表包含名稱和l_name(名稱列的小寫)等列。我試圖迭代我的​​表空間中的所有列,以將l_列設置爲它們各自的大寫字母列的小寫字母。這裏是我的嘗試:Oracle:使用動態列名更新表

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列的較低值更新表。這給了我一個錯誤說:

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` 

你能幫助我,我做的方式或其他方式,它可以做什麼?

+0

這是我工作表中唯一的東西,第8行包含'立即執行'語句 – rav

+0

你沒有'begin'和'end'這個字符嗎?還有一個關於'my_temp_storage'的聲明? –

+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; 

似乎一個奇怪的數據庫設計雖然。您是否考慮過虛擬列和/或基於函數的索引,而不是手動維護的列?

+0

我嘗試了類似的東西。但是,LOWER('|| substr(i.columm_name,3))從同一列(即L_列)返回子字符串。 – rav

+0

它將列的**名稱**進行子串排序而不是它的值,所以它無關緊要? –

+0

這是行得通的。非常感謝。我之前嘗試的方式是:LOWER(substr('|| i.columm_name ||',3)實際上給出了同一列的小寫值 – rav