我相当是PL / SQL的新手,并且正在使用Oracle SQL Developer编写一个过程,该过程使用序列为某些现有数据生成主键,以写入另一个DB。
有问题的代码属于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:begin,function,package,pragma,procedure,...
答案 0 :(得分: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;
请记住,序列是数据库中的持久对象。每次要使用它时都无需删除并重新创建它。如果您要运行脚本,然后重新运行它,序列将很乐意继续增加返回值。
答案 1 :(得分:2)
您无法在DECLARE程序块中创建序列。在BEGIN之后移动它。但是,如果它有意义,这是有争议的。您可能需要首先在程序之外创建它。
更新
实际上,如果您真的想在BEGIN / END中使用以下内容:
EXECUTE IMMEDIATE 'CREATE SEQUENCE mySequence START WITH 0 INCREMENT BY 1';
答案 2 :(得分: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创建,但我认为这不是你想要的。