用于在表上自动生成 ID 的序列和触发 PL/SQL 脚本
Posted
技术标签:
【中文标题】用于在表上自动生成 ID 的序列和触发 PL/SQL 脚本【英文标题】:Sequence and Trigger PL/SQL script for Automatic ID generation on a table 【发布时间】:2013-08-07 13:23:13 【问题描述】:谁能帮我修复那个代码。它不能在 PL/SQL (SQLPLUS @script.sql) 上运行,给出 SP2-0552:未声明绑定变量“NEW”。
脚本.SQL
prompt Creating Table SYSTEMDATALOG;
declare
counter1 integer;
counter2 integer;
begin
SELECT COUNT(*) INTO counter1 FROM ALL_TABLES WHERE TABLE_NAME='SYSTEMDATALOG' AND OWNER='MZMESDB';
if counter1 = 1 then
DROP TABLE SYSTEMDATALOG;
end if;
SELECT COUNT(*) INTO counter2 FROM ALL_SEQUENCES WHERE SEQUENCE NAME='SEQSYSTEMDATALOG';
if counter2 = 1 then
DROP SEQUENCE SEQSYSTEMDATALOGID;
endif;
CREATE TABLE "MZMESDB"."SYSTEMDATALOG" ( "ID" INTEGER NOT NULL ,
"DATETIME" DATE NOT NULL ,
"TYPE" VARCHAR2(64) NOT NULL,
"SEVERITY" INTEGER NOT NULL,
"SOURCE" VARCHAR2(64) NOT NULL,
"USER" VARCHAR2(64) NOT NULL,
"MESSAGE" VARCHAR2(1024), PRIMARY KEY ("ID") VALIDATE );
CREATE SEQUENCE SEQSYSTEMDATALOGID;
CREATE OR REPLACE TRIGGER TRIGSYSTEMDATALOGID
BEFORE INSERT ON SYSTEMDATALOG
FOR EACH ROW
BEGIN
SELECT SEQSYSTEMDATALOGID.NEXTVAL INTO :NEW.ID FROM DUAL;
END TRIGSYSTEMDATALOGID;
end;
/
提前感谢您的任何帮助。
[确定代码]
提示创建表SYSTEMDATALOG;
声明 counter1 整数; counter2 整数;
开始 SELECT COUNT(*) INTO counter1 FROM ALL_TABLES WHERE TABLE_NAME='SYSTEMDATALOG' AND OWNER='MZMESDB';
if counter1 = 1 then
execute immediate 'DROP TABLE SYSTEMDATALOG';
end if;
SELECT COUNT(*) INTO counter2 FROM ALL_SEQUENCES WHERE SEQUENCE_NAME='SEQSYSTEMDATALOG';
IF counter2 = 1 then
execute immediate 'DROP SEQUENCE SEQSYSTEMDATALOGID';
END IF;
execute immediate 'CREATE TABLE "MZMESDB"."SYSTEMDATALOG" (
"ID" INTEGER NOT NULL ,
"DATETIME" DATE NOT NULL ,
"TYPE" VARCHAR2(64) NOT NULL,
"SEVERITY" INTEGER NOT NULL,
"SOURCE" VARCHAR2(64) NOT NULL,
"USER" VARCHAR2(64) NOT NULL,
"MESSAGE" VARCHAR2(1024), PRIMARY KEY ("ID") VALIDATE )';
execute immediate 'CREATE SEQUENCE SEQSYSTEMDATALOGID';
execute immediate 'CREATE OR REPLACE TRIGGER TRIGSYSTEMDATALOGID
BEFORE INSERT ON SYSTEMDATALOG
FOR EACH ROW
BEGIN
SELECT SEQSYSTEMDATALOGID.NEXTVAL INTO :NEW.ID FROM DUAL;
END TRIGSYSTEMDATALOGID;';
结束;
【问题讨论】:
【参考方案1】:一个问题是您正在混合使用 PL/SQL(一个匿名 PL/SQL 块)和 DDL。虽然您可以在 PL/SQL 中编写 DML 语句(SELECT/INSERT/UPDATE/DELETE),但您不能直接在 PL/SQL 中编写 DDL(CREATE/DROP 等)。
您需要在匿名 PL/SQL 块之外运行 DDL 语句或使用
EXECUTE IMMEDIATE '<statement>';
.
至于:NEW
上的错误,我认为当您解决其他问题时它会消失。如果没有,请尝试添加:
SET SCAN OFF
在 SQL*Plus 文件的开头。
【讨论】:
我使用 EXECUTE IMMEDIATE 也没有成功。我更改了脚本,因为它不起作用... 您的立即执行代码中有一些语法错误: 1.end if;
拼写错误为 endif;
2. 一些字符串常量没有被撇号包围(SYSTEMDATALOG
应该是 @987654327 @)。
Endif 确实是一个错误。我试过带引号和不带引号,行为是一样的。即使修复了 endif,当 PL/SQL 处理器的最后一行出现以下情况之一时,我仍然会得到“遇到符号“;”。
我试过了(虽然我用SELECT 1 FROM DUAL
交换了所有DDL),当我修复endif
时,错误消息消失了。
我更改了帖子标题并添加了最终的工作代码。浪费了几个小时,但这对其他人可能有用。感谢您的帮助。以上是关于用于在表上自动生成 ID 的序列和触发 PL/SQL 脚本的主要内容,如果未能解决你的问题,请参考以下文章
用于从序列生成 id 的 Oracle 触发器的 HIbernate 问题