微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用立即执行的 Oracle 更改表未按预期运行

如何解决使用立即执行的 Oracle 更改表未按预期运行

我有像下面这样的 PLsql 块,它添加一个虚拟列,进行更新,然后删除重命名

MenuItem

一个立即执行语句成功,但新创建的列上的以下 UPDATE 语句失败并显示以下错误

BEGIN
NULL;
EXECUTE IMMEDIATE 'ALTER TABLE TESTMISMATCH ADD (TEMP_745634_1 VARCHAR2(4000 BYTE))';
UPDATE TESTMISMATCH SET TEMP_745634_1=TO_CHAR(A);
EXECUTE IMMEDIATE 'ALTER TABLE TESTMISMATCH DROP COLUMN A';
EXECUTE IMMEDIATE 'ALTER TABLE TESTMISMATCH RENAME COLUMN TEMP_745634_1 TO A';
End; 

但是如果我在没有 plsql 块的情况下运行相同的语句,则所有语句都会成功执行,如下所示。

ORA-06550: line 4,column 25:
PL/sql: ORA-00904: "TEMP_745634_1": invalid identifier
ORA-06550: line 4,column 1:

我最初的怀疑是关于在 First“Execute Immediate”语句和 Update 语句之间发生的 PLsql 上下文和 sql 上下文切换。

解决方法

问题是 Oracle 必须先编译 PL/SQL 块,然后才能执行它。当它尝试编译块时,它发现 temp_745634_1 不是有效的列名并抛出错误。这发生在 Oracle 甚至可以尝试执行包括 execute immediate 在内的单个语句之前。

如果要在创建它的同一 PL/SQL 块中引用新创建的列,则需要将编译推迟到运行时。为此,您需要使 update 语句使用动态 SQL。因此,如果您执行 execute immediate 'update ...,PL/SQL 块将起作用。

,

看起来您在第一步中所做的更改在块结束之前是不可见的。

这对你有帮助

BEGIN
  EXECUTE IMMEDIATE 'ALTER TABLE TESTMISMATCH ADD (TEMP_745634_1 VARCHAR2(4000 BYTE))';  
  execute immediate 'UPDATE TESTMISMATCH SET TEMP_745634_1=TO_CHAR(''A'')';
  EXECUTE IMMEDIATE 'ALTER TABLE TESTMISMATCH DROP COLUMN A';
  EXECUTE IMMEDIATE 'ALTER TABLE TESTMISMATCH RENAME COLUMN TEMP_745634_1 TO A';
End; 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。