gpt4 book ai didi

oracle - 为什么这里需要立即执行?

转载 作者:行者123 更新时间:2023-12-04 23:18:35 25 4
gpt4 key购买 nike

我是一名 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 语句改成了这个,现在它又可以工作了:
ELSE
EXECUTE IMMEDIATE 'insert into test (hello) values (''hi'')';

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

最佳答案

整个 PL/SQL 块在编译时被解析,但动态语句中的文本直到运行时才会被评估。 (对于匿名块,它们几乎相同,但步骤仍然不同)。

您的 if/else 也不会在运行时评估。编译器不知道在您进行插入时该表将始终存在,它只能在解析整个块时检查它是否存在。

如果该表已经存在,则可以;编译器可以看到它,块执行,您的选择获得 1,然后您进入 else 进行插入。但是,如果它不存在,则插入的解析在编译时正确地失败并显示 ORA-00942,并且块中的任何内容都不会执行。

由于表的创建是动态的,因此对表的所有引用也必须是动态的 - 如您所见,您的插入,但如果您随后查询它,也是如此。基本上它使您的代码更难阅读并且可以隐藏语法错误 - 因为动态代码直到运行时才被解析,并且您可能在一个没有被命中的分支中的动态语句中出错很久。

全局temporary tables无论如何都不应该即时创建。它们是具有临时数据的永久对象,特定于每个 session ,不应作为应用程序代码的一部分创建/删除。 (您的应用程序通常不应更改架构;它们应仅限于升级/维护更改并受到控制,以避免错误、数据丢失和意外副作用;GTT 也不异常(exception))。

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 .

关于oracle - 为什么这里需要立即执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33628951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com