创建触发器并插入新值

时间:2015-02-18 20:06:56

标签: sql oracle triggers oracle11g

我有一个Oracle 11g脚本来创建一个表,一个用序列更新主键的触发器,以及为行插入语句。当我尝试运行整个脚本时,它失败并显示消息:

错误(6,1):PLS-00103:遇到符号“INSERT”

以下是代码:

    CREATE TABLE LOCATION(
  LOC_ID INTEGER  PRIMARY KEY,
  LOC_NAME VARCHAR(255) NOT NULL,
  LOC_STREET VARCHAR(255) NOT NULL,
  LOC_CITY VARCHAR(127) NOT NULL,
  LOC_STATE CHAR(2) NOT NULL CHECK (REGEXP_LIKE (LOC_STATE,'[A-Z][A-Z]')),
  LOC_ZIPCODE CHAR(9) CHECK (LOC_ZIPCODE BETWEEN 1 AND 999999999) ,
  LOC_AREACODE CHAR(3), CHECK (LOC_AREACODE BETWEEN 1 AND 999),
  LOC_PHONE CHAR(7) NOT NULL UNIQUE CHECK (LOC_PHONE BETWEEN 1 AND 9999999)
  );

CREATE SEQUENCE LOC_NUM_UPDATE START WITH 100 INCREMENT BY 5;

CREATE OR REPLACE TRIGGER NEW_LOC_NUM
  BEFORE INSERT ON LOCATION
  FOR EACH ROW
BEGIN
  SELECT LOC_NUM_UPDATE.NEXTVAL
    INTO :NEW.LOC_ID
    FROM DUAL;
END;

INSERT INTO LOCATION VALUES(1,'Stubbs','801 Red River St', 'Austin', 'TX', '78701','512','4808341');
INSERT INTO LOCATION VALUES(1,'Backyard','13801 Bee Cave Pkwy', 'Austin', 'TX', '78738','512','6515033');
INSERT INTO LOCATION VALUES(1,'Emo''s','2015 E Riverside Dr', 'Austin', 'TX', '78741','512','4808341');
INSERT INTO LOCATION VALUES(1,'Mohawk','912 Red River St', 'Austin', 'TX', '78701','512','5670653');
INSERT INTO LOCATION VALUES(1,'Continental','1315 S Congress Ave', 'Austin', 'TX', '78704','512','4412444');
INSERT INTO LOCATION VALUES(1,'Broken Spoke','3201 S Lamar Blvd', 'Austin', 'TX', '78704','512','4426189');

那么,有没有办法'逃避'CREATE TRIGGER活动以在'END;'之后插入值?

3 个答案:

答案 0 :(得分:0)

尝试了几种方法之后,最后我得到了你需要用Dynamic SQL执行所有DDL语句并使用SET SCAN OFF;命令,因为你使用:NEW;

SET SCAN OFF;
execute immediate 'CREATE TABLE LOCATION(
  LOC_ID INTEGER  PRIMARY KEY,
  LOC_NAME VARCHAR(255) NOT NULL,
  LOC_STREET VARCHAR(255) NOT NULL,
  LOC_CITY VARCHAR(127) NOT NULL,
  LOC_STATE CHAR(2) NOT NULL CHECK (REGEXP_LIKE (LOC_STATE,''[A-Z][A-Z]'')),
  LOC_ZIPCODE CHAR(9) CHECK (LOC_ZIPCODE BETWEEN 1 AND 999999999) ,
  LOC_AREACODE CHAR(3), CHECK (LOC_AREACODE BETWEEN 1 AND 999),
  LOC_PHONE CHAR(7) NOT NULL UNIQUE CHECK (LOC_PHONE BETWEEN 1 AND 9999999)
  )';
  execute immediate'
CREATE SEQUENCE LOC_NUM_UPDATE START WITH 100 INCREMENT BY 5';
execute immediate'
CREATE OR REPLACE TRIGGER NEW_LOC_NUM
  BEFORE INSERT ON LOCATION
  FOR EACH ROW
BEGIN
  SELECT LOC_NUM_UPDATE.NEXTVAL
    INTO :NEW.LOC_ID
    FROM DUAL;
END';
end;

答案 1 :(得分:0)

这里有很多问题。数据类型,触发后缺少执行命令(例如/),并且当触发器将负责为其分配值时,尝试在更新语句中为loc_id分配值。

  • 我倾向于使用NUMBER(10,0)(使用你的精确度 需要)INTEGER这是可接受的,但不是传统的。

  • 关于VARCHAR数据类型,Oracle希望我们使用 VARCHAR2数据类型。

  • 关于使用CHAR,state,city的固定宽度数据类型 区号和电话号码,你真的想要固定宽度吗?我会使用VARCHAR2

我在触发器后添加了一个执行命令/,并修改了insert语句以解决触发器活动。

这是您修改的ddl和dml:

CREATE TABLE LOCATION
  (
    LOC_ID       INTEGER PRIMARY KEY,
    LOC_NAME     VARCHAR(255) NOT NULL,
    LOC_STREET   VARCHAR(255) NOT NULL,
    LOC_CITY     VARCHAR(127) NOT NULL,
    LOC_STATE    CHAR(2) NOT NULL CHECK (REGEXP_LIKE (LOC_STATE,'[A-Z][A-Z]')),
    LOC_ZIPCODE  CHAR(9) CHECK (LOC_ZIPCODE BETWEEN 1 AND 999999999) ,
    LOC_AREACODE CHAR(3),
    CHECK (LOC_AREACODE BETWEEN 1 AND 999),
    LOC_PHONE CHAR(7) NOT NULL UNIQUE CHECK (LOC_PHONE BETWEEN 1 AND 9999999)
  );
CREATE SEQUENCE LOC_NUM_UPDATE START WITH 100 INCREMENT BY 5;
CREATE OR REPLACE TRIGGER NEW_LOC_NUM BEFORE
  INSERT ON LOCATION FOR EACH ROW BEGIN
  SELECT LOC_NUM_UPDATE.NEXTVAL INTO :NEW.LOC_ID FROM DUAL;
END;
/
INSERT
INTO LOCATION
  (
    LOC_NAME,
    LOC_STREET,
    LOC_CITY,
    LOC_STATE,
    LOC_ZIPCODE,
    LOC_AREACODE,
    LOC_PHONE
  )
  VALUES
  (
    'Stubbs',
    '801 Red River St',
    'Austin',
    'TX',
    '78701',
    '512',
    '4808341'
  );
INSERT
INTO LOCATION
  (
    LOC_NAME,
    LOC_STREET,
    LOC_CITY,
    LOC_STATE,
    LOC_ZIPCODE,
    LOC_AREACODE,
    LOC_PHONE
  )
  VALUES
  (
    'Backyard',
    '13801 Bee Cave Pkwy',
    'Austin',
    'TX',
    '78738',
    '512',
    '6515033'
  );

这是执行此ddl和dml:

  SCOTT@erp> CREATE TABLE LOCATION
      2    (
      3      LOC_ID       INTEGER PRIMARY KEY,
      4      LOC_NAME     VARCHAR(255) NOT NULL,
      5      LOC_STREET   VARCHAR(255) NOT NULL,
      6      LOC_CITY     VARCHAR(127) NOT NULL,
      7      LOC_STATE    CHAR(2) NOT NULL CHECK (REGEXP_LIKE (LOC_STATE,'[A-Z][A-Z]')),
      8      LOC_ZIPCODE  CHAR(9) CHECK (LOC_ZIPCODE BETWEEN 1 AND 999999999) ,
      9      LOC_AREACODE CHAR(3),
     10      CHECK (LOC_AREACODE BETWEEN 1 AND 999),
     11      LOC_PHONE CHAR(7) NOT NULL UNIQUE CHECK (LOC_PHONE BETWEEN 1 AND 9999999)
     12    );

    Table created.

    SCOTT@erp> CREATE SEQUENCE LOC_NUM_UPDATE START WITH 100 INCREMENT BY 5;

    Sequence created.

    SCOTT@erpdev> CREATE OR REPLACE TRIGGER NEW_LOC_NUM BEFORE
      2    INSERT ON LOCATION FOR EACH ROW BEGIN
      3    SELECT LOC_NUM_UPDATE.NEXTVAL INTO :NEW.LOC_ID FROM DUAL;
      4  END;
      5  /

    Trigger created.

    SCOTT@erp> INSERT
      2  INTO LOCATION
      3    (
      4      LOC_NAME,
      5      LOC_STREET,
      6      LOC_CITY,
      7      LOC_STATE,
      8      LOC_ZIPCODE,
      9      LOC_AREACODE,
     10      LOC_PHONE
     11    )
     12    VALUES
     13    (
     14      'Stubbs',
     15      '801 Red River St',
     16      'Austin',
     17      'TX',
     18      '78701',
     19      '512',
     20      '4808341'
     21    );

    1 row created.

    SCOTT@erp> INSERT
      2  INTO LOCATION
      3    (
      4      LOC_NAME,
      5      LOC_STREET,
      6      LOC_CITY,
      7      LOC_STATE,
      8      LOC_ZIPCODE,
      9      LOC_AREACODE,
     10      LOC_PHONE
     11    )
     12    VALUES
     13    (
     14      'Backyard',
     15      '13801 Bee Cave Pkwy',
     16      'Austin',
     17      'TX',
     18      '78738',
     19      '512',
     20      '6515033'
     21    );

    1 row created.

答案 2 :(得分:0)

我以这种方式更改了你的脚本(只是一些格式化)并且在SQL plus中为我工作(我必须更改第三个插入loc_phone值,因为它有唯一的约束)

CREATE TABLE location(
LOC_ID INTEGER  PRIMARY KEY,
LOC_NAME VARCHAR(255) NOT NULL,
LOC_STREET VARCHAR(255) NOT NULL,
LOC_CITY VARCHAR(127) NOT NULL,
LOC_STATE CHAR(2) NOT NULL CHECK (REGEXP_LIKE (LOC_STATE,'[A-Z][A-Z]')),
LOC_ZIPCODE CHAR(9) CHECK (LOC_ZIPCODE BETWEEN 1 AND 999999999) ,
LOC_AREACODE CHAR(3) CHECK (LOC_AREACODE BETWEEN 1 AND 999),
LOC_PHONE CHAR(7) NOT NULL UNIQUE CHECK (LOC_PHONE BETWEEN 1 AND 9999999)
);
CREATE SEQUENCE LOC_NUM_UPDATE START WITH 100 INCREMENT BY 5;
/
CREATE OR REPLACE TRIGGER NEW_LOC_NUM
BEFORE INSERT ON location
FOR EACH ROW
BEGIN
SELECT LOC_NUM_UPDATE.NEXTVAL
INTO :NEW.LOC_ID
FROM DUAL;
END;
/
INSERT INTO location VALUES(1,'Stubbs','801 Red River St', 'Austin', 'TX',         '78701','512','4808341');
INSERT INTO location VALUES(1,'Backyard','13801 Bee Cave Pkwy', 'Austin', 'TX', '78738','512','6515033');
INSERT INTO location VALUES(1,'Emo''s','2015 E Riverside Dr', 'Austin', 'TX', '78741','512','4808342');
INSERT INTO location VALUES(1,'Mohawk','912 Red River St', 'Austin', 'TX', '78701','512','5670653');
INSERT INTO location VALUES(1,'Continental','1315 S Congress Ave', 'Austin', 'TX', '78704','512','4412444');
INSERT INTO location VALUES(1,'Broken Spoke','3201 S Lamar Blvd', 'Austin', 'TX', '78704','512','4426189');