5

我对 PL/SQL陌生,并且正在使用 Oracle SQL Developer 编写一个过程,该过程使用序列为一些现有数据生成主键,以写入另一个数据库。

有问题的代码在 NDA 下。基本上我有以下内容:

create or replace
PROCEDURE Generate_Data
(
   output IN VARCHAR2
) 
AS

-- Variables here --

CURSOR myCursor IS
SELECT data1, data2 
FROM table;

CREATE SEQUENCE mySequence      <-- error on this line
START WITH 0
INCREMENT BY 1;

BEGIN
LOOP
    -- snip --

它引发错误 PLS-00103,说它在预期以下内容时遇到符号 CREATE:开始、函数、包、编译指示、过程...

我一直在关注这个例子: http ://www.techonthenet.com/oracle/sequences.php

4

3 回答 3

7

您收到此错误的原因是您正在尝试执行DDL,在本例中是在 PL/SQL 中创建一个序列。可以这样做,但您必须使用execute immediate.

正如Alex所说,您也无法在该declare部分中执行此操作。它看起来像这样:

begin

   execute immediate 'CREATE SEQUENCE mySequence
                          START WITH 0
                          INCREMENT BY 1';    
end;

然而,正如Padmarag所说,您不太可能希望在 PL/SQL 中执行此操作。在外面创建一个序列然后再引用它会更正常。更一般地说,在 PL/SQL 块中执行 DDL 是个坏主意。你应该没有必要这样做。

您没有提及您使用的是哪个版本的 Oracle。从 11g 开始,您访问序列的方式得到了扩展。如果您使用的是 11g,那么您可以通过创建一个变量并将序列中的下一个值 分配给该变量来访问该序列.nextval

declare    
   l_seq number;    
begin

   loop
      -- For each loop l_seq will be incremented.
      l_seq := mysequence.nextval;
   -- snip    
end;

如果您在 11g 之前,则必须(在DML之外)使用 select 语句才能获得下一个值:

declare
   l_seq number;
begin

   loop
      -- For each loop l_seq will be incremented.
      select mysequence.nextval into l_seq from dual;
   -- snip    
end;

请记住,序列是数据库中的持久对象。每次您想使用它时,无需删除并重新创建它。如果你要运行你的脚本,然后重新运行它,序列会很高兴地不断增加返回值。

延伸阅读

于 2012-07-03T19:44:25.083 回答
2

您不能在 DECLARE 程序块中创建序列。在 BEGIN 之后移动它。不过,如果它有意义,这是有争议的。您可能首先需要在您的程序之外创建它。


更新

实际上,如果你真的想在 BEGIN/END 中使用它:

EXECUTE IMMEDIATE 'CREATE SEQUENCE mySequence  START WITH 0 INCREMENT BY 1'; 
于 2012-07-03T19:31:37.287 回答
0

您需要在使用它之前创建序列。

并在 PL/SQL 代码中使用
-- Variables here --1
v_seq_val number;

BEGIN
Select mySequence.nextval from dual into v_seq_val

一般来说,SQL 用于 DDL(数据定义语言),PL/SQL 用于 DML(数据操作语言)和逻辑。

如果你愿意,你可以从 PL/SQL 创建,但我认为这不是你想要的。

于 2012-07-03T19:29:09.823 回答