Oracle Alter Table 使用 Execute Immediate 未按预期运行

Oracle Alter Table using Execute Immediate Not behaving as expected

我有如下所示的 PLSQL 块,其中添加了一个虚拟列,进行了更新,然后删除并重命名了列

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; 

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

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

但是如果我 运行 没有 plsql 块,所有语句都成功执行,如下所示。

ALTER TABLE TESTMISMATCH ADD (TEMP_745634_1 VARCHAR2(4000 BYTE));
UPDATE TESTMISMATCH SET TEMP_745634_1=TO_CHAR(A);
ALTER TABLE TESTMISMATCH DROP COLUMN A;
ALTER TABLE TESTMISMATCH RENAME COLUMN TEMP_745634_1 TO A;

我最初的怀疑是,关于 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;