我是 Oracle 脚本编写新手,在将数据插入全局临时表时遇到问题。这是我在 Toad 中创建的脚本:
SET SERVEROUTPUT ON;
DECLARE
tempTwwIDExist NUMBER;
v_sql LONG;
BEGIN
SELECT COUNT(*) INTO tempTwwIDExist FROM USER_TABLES WHERE table_name = UPPER('tempTwwID');
DBMS_OUTPUT.PUT_LINE(tempTwwIDExist);
IF (tempTwwIDExist > 0) THEN
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE tempTwwID';
EXECUTE IMMEDIATE 'DROP TABLE tempTwwID';
END;
END IF;
EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE tempTwwID (id NUMBER NOT NULL, SITEID NUMBER) ON COMMIT DELETE ROWS';
EXECUTE IMMEDIATE 'INSERT INTO tempTwwID (id, SITEID) VALUES (1,123)';
END;
/
但是,当我运行 SELECT 语句以从 tempTwwID 获取所有数据时,尽管此脚本使用 EXECUTE IMMEDIATE 运行 INSERT 语句(END 之前的最后一行代码;),现在仍会返回行。
我希望你能帮我解决这个问题。提前致谢。
最佳答案
您已使用ON COMMIT DELETE ROWS
定义了全局临时表。如果您在匿名 block 内显式提交(无论是否通过立即执行
),这是毫无意义的 - 或者在该 block 之后显式提交,则该 session 中的后续查询将不再看到插入的数据。
可能不太明显的是 Toad can be configured to auto-commit 。如果设置了该值,则 block 中的更改将在运行后立即自动提交,这意味着在 block 中插入的行将在您查询之前被删除。如果将 GTT 更改为 ON COMMIT PRESERVE ROWS
,您将在查询时看到数据。
这不仅限于蟾蜍;您可以通过 set autocommit on
在 SQL Developer 或 SQL*Plus 中看到相同的内容。如果您没有充分的理由自动提交,那么您可以将其关闭。
正如 Jeffrey Kemp 所说,您不应该在运行时创建 GTT(或进行任何架构修改);模式应该是受控的和静态的。 Oracle 的 GTT 与您在其他数据库中动态定义的本地临时表不同,并且应该创建一次。 It is the data that is temporary, not the table object .
在运行时定义事物会进行您可能不期望的隐式提交(自 DDL commits 起),成本高昂,存在 session 之间发生冲突的风险,并迫使您在不需要的地方使用动态 SQL;这反过来又阻止了在编译时检查代码,这意味着直到运行时才会看到语法错误。
关于oracle - INSERT 不适用于 PL/SQL block 中的 GLOBAL TEMPORARY TABLE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32173818/