Oracle PL/SQL 在游标中创建表?
Oracle PL/SQL Creating tables in cursor?
我对 PL/SQL 比较陌生,所以请多多包涵。
我正在创建两个将在 FOR 循环游标中使用的表。我的意图是在开始时(游标循环之前)创建这两个表,每当我需要清除它们时在游标循环内截断它们并插入新值,然后在游标循环完成后将它们删除。
(在稍微了解一下 SO 之后,我认为这可以用 REF CURSOR 来完成,但我不太清楚如何使用它,所以我决定继续使用第一种方法。)
我尝试在 DECLARE 部分创建表,然后在循环开始之前在 BEGIN 部分创建表,但它引发了错误 'ORA-065500 and PLS-00103 Encountered the symbol CREATE when expecting begin function pragma ...'
请注意,我在 LOOP 结束后但在游标的 END 部分之前删除表。
我是否应该在游标外部、DECLARE 部分之前创建表,然后将它们删除到游标 END 部分之后?我认为应该可以在游标内创建永久 oracle 表?
更新:在此处发布代码-
1)
DECLARE
CREATE TABLE T1
(
col1 VARCHAR2(128),
col2 VARCHAR2(128),
col3 NUMBER(3) NOT NULL,
col3 FLOAT(100)
);
CREATE TABLE T2 AS
SELECT * FROM other_table WHERE 1 = 0;
CURSOR CUR IS ...
BEGIN
FOR rec IN CUR
LOOP
--Do stuff here
END LOOP;
Drop table T1;
Drop table T2;
END;
/
2)
DECLARE
CURSOR CUR IS ...
BEGIN
CREATE TABLE T1
(
col1 VARCHAR2(128),
col2 VARCHAR2(128),
col3 NUMBER(3) NOT NULL,
col3 FLOAT(100)
);
CREATE TABLE T2 AS
SELECT * FROM other_table WHERE 1 = 0;
FOR rec IN CUR
LOOP
--Do stuff here
END LOOP;
Drop table T1;
Drop table T2;
END;
/
(1) 和 (2) 均无效。
更新 - 我们需要为此立即执行吗?我怎么知道什么时候需要立即执行?我们还需要 EXECUTE IMMEDIATE 来截断游标中的表吗?
通常您不会在 PL/SQL 过程中执行 DDL(创建、更改、删除)。如果您需要 table 来存储一些临时数据,您可以为此创建 temporary tables。在你的情况下,我会首先创建 tables
CREATE GLOBAL TEMPORARY TABLE T1
(
col1 VARCHAR2(128),
col2 VARCHAR2(128),
col3 NUMBER(3) NOT NULL,
col3 FLOAT(100)
);
CREATE GLOBAL TEMPORARY TABLE T2 AS
SELECT * FROM other_table WHERE 1 = 0;
然后程序看起来像这样
DECLARE
CURSOR CUR IS ...
BEGIN
FOR rec IN CUR
LOOP
--Do stuff here
END LOOP;
DELETE FROM T1;
DELETE FROM T2;
END;
/
当然 tables 之后不会被删除,但我想你想定期使用你的 PL/SQL 程序,而不是一次,对吗?
如果您仍想在程序中执行 DDL,则必须使用 dynamic sql(立即执行)。但是您必须知道 DDL 操作执行隐式提交,因此您的过程不会是单个原子事务。
我对 PL/SQL 比较陌生,所以请多多包涵。 我正在创建两个将在 FOR 循环游标中使用的表。我的意图是在开始时(游标循环之前)创建这两个表,每当我需要清除它们时在游标循环内截断它们并插入新值,然后在游标循环完成后将它们删除。 (在稍微了解一下 SO 之后,我认为这可以用 REF CURSOR 来完成,但我不太清楚如何使用它,所以我决定继续使用第一种方法。)
我尝试在 DECLARE 部分创建表,然后在循环开始之前在 BEGIN 部分创建表,但它引发了错误 'ORA-065500 and PLS-00103 Encountered the symbol CREATE when expecting begin function pragma ...' 请注意,我在 LOOP 结束后但在游标的 END 部分之前删除表。
我是否应该在游标外部、DECLARE 部分之前创建表,然后将它们删除到游标 END 部分之后?我认为应该可以在游标内创建永久 oracle 表?
更新:在此处发布代码-
1)
DECLARE
CREATE TABLE T1
(
col1 VARCHAR2(128),
col2 VARCHAR2(128),
col3 NUMBER(3) NOT NULL,
col3 FLOAT(100)
);
CREATE TABLE T2 AS
SELECT * FROM other_table WHERE 1 = 0;
CURSOR CUR IS ...
BEGIN
FOR rec IN CUR
LOOP
--Do stuff here
END LOOP;
Drop table T1;
Drop table T2;
END;
/
2)
DECLARE
CURSOR CUR IS ...
BEGIN
CREATE TABLE T1
(
col1 VARCHAR2(128),
col2 VARCHAR2(128),
col3 NUMBER(3) NOT NULL,
col3 FLOAT(100)
);
CREATE TABLE T2 AS
SELECT * FROM other_table WHERE 1 = 0;
FOR rec IN CUR
LOOP
--Do stuff here
END LOOP;
Drop table T1;
Drop table T2;
END;
/
(1) 和 (2) 均无效。
更新 - 我们需要为此立即执行吗?我怎么知道什么时候需要立即执行?我们还需要 EXECUTE IMMEDIATE 来截断游标中的表吗?
通常您不会在 PL/SQL 过程中执行 DDL(创建、更改、删除)。如果您需要 table 来存储一些临时数据,您可以为此创建 temporary tables。在你的情况下,我会首先创建 tables
CREATE GLOBAL TEMPORARY TABLE T1
(
col1 VARCHAR2(128),
col2 VARCHAR2(128),
col3 NUMBER(3) NOT NULL,
col3 FLOAT(100)
);
CREATE GLOBAL TEMPORARY TABLE T2 AS
SELECT * FROM other_table WHERE 1 = 0;
然后程序看起来像这样
DECLARE
CURSOR CUR IS ...
BEGIN
FOR rec IN CUR
LOOP
--Do stuff here
END LOOP;
DELETE FROM T1;
DELETE FROM T2;
END;
/
当然 tables 之后不会被删除,但我想你想定期使用你的 PL/SQL 程序,而不是一次,对吗?
如果您仍想在程序中执行 DDL,则必须使用 dynamic sql(立即执行)。但是您必须知道 DDL 操作执行隐式提交,因此您的过程不会是单个原子事务。