Chr*_*ven 2 oracle toad global temporary
我是 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;
/
Run Code Online (Sandbox Code Playgroud)
但是,当我运行 SELECT 语句以从 tempTwwID 获取所有数据时,尽管此脚本使用 EXECUTE IMMEDIATE 运行 INSERT 语句(END; 之前的最后一行代码),但现在仍返回行。
我希望你能帮我解决这个问题。提前致谢。
您已使用 定义了全局临时表ON COMMIT DELETE ROWS。如果您在匿名块内显式提交(无论是否通过execute immediate,这是毫无意义的)或在该块之后显式提交,则该会话中的后续查询将不再看到插入的数据。
可能不太明显的是Toad 可以配置为自动提交。如果设置了该值,则块中的更改将在运行后立即自动提交,这意味着在块中插入的行将在您查询之前被删除。如果将 GTT 更改为,ON COMMIT PRESERVE ROWS您将在查询时看到数据。
这不仅限于蟾蜍。您可以在 SQL Developer 或 SQL*Plus 中看到同样的事情set autocommit on。如果您没有充分的理由自动提交,那么您可以将其关闭。
正如 Jeffrey Kemp 所说,您不应该在运行时创建 GTT(或进行任何模式修改);模式应该是受控的和静态的。Oracle 的 GTT 与您在其他数据库中动态定义的本地临时表不同,并且应该创建一次。临时数据是数据,而不是表对象。
在运行时定义事物会进行您可能不期望的隐式提交(因为DDL 提交),成本高昂,存在会话之间发生冲突的风险,并迫使您在不需要的地方使用动态 SQL;这反过来又阻止了在编译时检查代码,这意味着直到运行时才会看到语法错误。