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

oracle – 为什么需要EXECUTE IMMEDIATE?

我是一个sql Server用户,我有一个小项目要使用Oracle,所以我试图了解Oracle的一些特性,我认为我需要一些帮助来更好地理解以下情况:

我想在创建临时表之前测试它是否存在,所以我在这里有这个代码

DECLARE
  table_count INTEGER;
  var_sql VARCHAR2(1000) := 'create GLOBAL TEMPORARY table TEST (
            hello varchar(1000) NOT NULL)';
BEGIN
  SELECT COUNT(*) INTO table_count FROM all_tables WHERE table_name = 'TEST';

  IF table_count = 0 THEN
    EXECUTE IMMEDIATE var_sql;
  END IF;
END;

它正常工作,所以在我执行一次后,我在我的IF上添加一个else语句:

ELSE
  insert into test (hello) values ('hi');

再次执行它,并在我的测试表中添加了一行.

好吧,我的代码准备就绪并且正常工作,所以我删除了临时表并尝试再次运行整个语句,但是当我这样做时,我收到以下错误

ORA-06550: line 11,column 19:
PL/sql: ORA-00942: table or view does not exist
ORA-06550: line 11,column 7:
PL/sql: sql Statement ignored
06550. 00000 -  "line %s,column %s:\n%s"
*Cause:    Usually a PL/sql compilation error.
*Action:

然后我将我的else语句更改为this,现在它再次起作用:

ELSE
  EXECUTE IMMEDIATE 'insert into test (hello) values (''hi'')';

我的问题是为什么单独运行我可以简单地使用插入而不是EXECUTE IMMEDIATE以及为什么我的SELECT语句在BEGIN之后仍然有效,而其他所有其他似乎都需要EXECUTE IMMEDIATE才能正常运行?

整个PL / sql块在编译时被解析,但动态语句中的文本直到运行时才被计算. (对于匿名块,它们接近同样的事情,但仍然是不同的步骤).

您的if / else在运行时之前也不会被评估.编译器不知道在插入时表总是存在,它只能在它解析整个块时检查它是否存在.

如果表已经存在则可以;编译器可以看到它,块执行,你的select得到1,然后你进入else进行插入.但是如果它不存在则在编译时使用ORA-00942正确解析插入,并且块中没有任何内容被执行.

由于表创建是动态的,因此对表的所有引用也必须是动态的 – 您看到的插入,但是如果您再查询它.基本上它会使您的代码更难以阅读并且可以隐藏语法错误 – 因为动态代码直到运行时才被解析,并且您可能在分支中的动态语句中有错误长时间.

无论如何,不​​应该动态创建全局temporary tables.它们是具有临时数据的永久对象,特定于每个会话,不应作为应用程序代码的一部分创建/删除. (一般情况下,您的应用程序不应进行架构更改;它们应限于升级/维护更改并进行控制,以避免错误,数据丢失和意外的副作用; GTT也不例外).

Unlike temporary tables in some other relational databases,when you create a temporary table in an Oracle database,you create a static table deFinition. The temporary table is a persistent object described in the data dictionary,but appears empty until your session inserts data into the table. You create a temporary table for the database itself,not for every PL/sql stored procedure.

创建一次GTT并使所有PL / sql代码保持静态.如果您想要更接近sql Server的本地临时表,请查看PL/SQL collections.

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

相关推荐