我有一个字段(clientID)在大多数我的表中重复(大约100左右),我正在尝试使用oracle 11g一次更新它。我能够得到表的名称,但我无法使用它。从下面的代码:
BEGIN
FOR Name IN ( SELECT TABLE_NAME FROM SYS.all_tables where TABLESPACE_NAME='MyTableSpace') LOOP
DBMS_OUTPUT.PUT_LINE(Name.TABLE_NAME); --I can't see any logs on DBMS Output for some reason
-- Update Name.TABLE_NAME set ClientID = 1 Where ClientID = 2; --This line does not work message "Table or view does not exist"
END LOOP;
END;
答案 0 :(得分:3)
您可以尝试使用EXECUTE IMMEDIATE
。
这样的事情:
BEGIN
FOR Name IN ( SELECT TABLE_NAME FROM SYS.all_tables where TABLESPACE_NAME='MyTableSpace') LOOP
DBMS_OUTPUT.PUT_LINE(Name.TABLE_NAME); --I can't see any logs on DBMS Output for some reason
EXECUTE IMMEDIATE 'Update ' || Name.TABLE_NAME || ' set ClientID = 1 Where ClientID = 2';
END LOOP;
END;
如果需要设置要动态更新的值,可以使用动态sql绑定参数。我只是不记得如何做到这一点。但如果您需要,请在评论中提问,我会寻找它。
修改强>
我认为如果要绑定值,它看起来像这样:
BEGIN
FOR Name IN ( SELECT TABLE_NAME FROM SYS.all_tables where TABLESPACE_NAME='MyTableSpace') LOOP
DBMS_OUTPUT.PUT_LINE(Name.TABLE_NAME); --I can't see any logs on DBMS Output for some reason
EXECUTE IMMEDIATE 'Update ' || Name.TABLE_NAME || ' set ClientID = :1 Where ClientID = :2'
USING 1, 2;
END LOOP;
END;
...而不是USING 1, 2
,您可以使用变量而不是硬编码常量值。
有关详细信息:EXECUTE IMMEDIATE。
编辑2
如果您需要跳过不存在相关列的表格,则以下是应该执行此操作的调整后的查询:
BEGIN
FOR Name IN (
SELECT t.TABLE_NAME
FROM all_tables t
where t.TABLESPACE_NAME='MyTableSpace'
and exists (
select null
from all_tab_columns c
where c.table_name = t.table_name
and c.column_name = 'CLIENTID' -- put the right column name here
)
) LOOP
DBMS_OUTPUT.PUT_LINE(Name.TABLE_NAME); --I can't see any logs on DBMS Output for some reason
EXECUTE IMMEDIATE 'Update ' || Name.TABLE_NAME || ' set ClientID = 1 Where ClientID = 2';
END LOOP;
END;
你可能需要稍微调整一下,因为我没有在我面前有一个Oracle数据库。我可能拼错了一些东西。