Oracle 10g Error: Warning: Trigger created with compilation errors
Oracle 10g Error: Warning: Trigger created with compilation errors
我已经创建了数据库,我想在其中自动增加主键。我试图触发它但出现上述错误
这是我对 table:
的描述
SQL> desc users
Name Null? Type
----------------------------------------- -------- ----------------------------
USER_ID NOT NULL NUMBER(8)
FIRST_NAME NOT NULL VARCHAR2(50)
LAST_NAME NOT NULL VARCHAR2(50)
CITY VARCHAR2(20)
COUNTRY VARCHAR2(20)
PASSWORD NOT NULL VARCHAR2(16)
EMAIL_ID NOT NULL VARCHAR2(50)
当我尝试触发它时出现错误:
CREATE SEQUENCE SYSTEM.MYSEQ
2 START WITH 1
3 MAXVALUE 99999999
4 MINVALUE 1
5 NOCYCLE
6 CACHE 20
7 NOORDER;
CREATE OR REPLACE TRIGGER TR_USERS BEFORE INSERT ON USERS FOR EACH ROW
2 BEGIN SELECT LPAD(LTRIM(RTRIM(TO_CHAR(MYSEQ.NEXTVAL))),10,'0') INTO :NEW.USER_ID FROM DUAL;
3 /
请帮我解决这个错误。
就 编译 而言,触发器没有任何问题(除了您“忘记”END
的事实)。
SQL> CREATE OR REPLACE TRIGGER TR_USERS
2 BEFORE INSERT ON USERS
3 FOR EACH ROW
4 BEGIN
5 SELECT lpad(ltrim(rtrim(to_char(myseq.nextval))), 10, '0')
6 INTO :new.user_id
7 FROM dual;
8 END;
9 /
Trigger created.
SQL> INSERT INTO USERS (FIRST_NAME) VALUES ('Little');
1 row created.
SQL> SELECT * FROM users;
USER_ID FIRST_NAME LAST_NAE CITY COUNTRY PASSW EMAIL_ID
---------- --------------- ---------- ---------- ---------- ----- --------------------
1 Little
SQL>
但是,如果 USER_ID
是 NUMBER
,那么您的触发器代码就过于复杂了,因为无论您使用这些函数做什么,最终都会得到一个 数。从我的示例中可以看出,USER_ID = 1
.
如果是VARCHAR2
,那么
SQL> TRUNCATE TABLE users;
Table truncated.
SQL> ALTER TABLE USERS MODIFY user_id VARCHAR2(10);
Table altered.
SQL> INSERT INTO USERS (FIRST_NAME) VALUES ('Foot');
1 row created.
SQL> SELECT * FROM users;
USER_ID FIRST_NAME LAST_NAE CITY COUNTRY PASSW EMAIL_ID
---------- --------------- ---------- ---------- ---------- ----- --------------------
0000000002 Foot
SQL>
看出区别了吗?
触发器本来可以更简单(但不是 更 更简单;毕竟你在 10g 上)因为没有什么可以 trim :
SQL> CREATE OR REPLACE TRIGGER TR_USERS
2 BEFORE INSERT ON USERS
3 FOR EACH ROW
4 BEGIN
5 SELECT lpad(to_char(myseq.nextval), 10, '0')
6 INTO :new.user_id
7 FROM dual;
8 END;
9 /
Trigger created.
SQL> INSERT INTO USERS (FIRST_NAME) VALUES ('Krishna');
1 row created.
SQL> SELECT * FROM users;
USER_ID FIRST_NAME LAST_NAE CITY COUNTRY PASSW EMAIL_ID
---------- --------------- ---------- ---------- ---------- ----- --------------------
0000000002 Foot
0000000003 Krishna
SQL>
您遇到错误,因为您缺少触发器的 END
:
CREATE OR REPLACE TRIGGER TR_USERS
BEFORE INSERT ON USERS
FOR EACH ROW
BEGIN
SELECT LPAD(LTRIM(RTRIM(TO_CHAR(MYSEQ.NEXTVAL))),10,'0')
INTO :NEW.USER_ID
FROM DUAL;
END; -- <=== this one
/
顺便说一句,触发器似乎没有多大意义。 LPAD(LTRIM(RTRIM(TO_CHAR(MYSEQ.NEXTVAL))),10,'0')
只是一个混淆的 TO_CHAR(MYSEQ.NEXTVAL, 'FM0000000000')
,但是,当 USERS.USER_ID
是数字时,为什么要创建一个带有前导零的字符串???你把 123 变成 '0000000123' 只是为了将它存储为 123.
除了缺少 end
关键字外,您不需要所有字符格式或 'select from dual'。我只会使用:
create or replace trigger tr_users
before insert on users
for each row
begin
:new.user_id := myseq.nextval;
end;
顺便说一句,你的序列也可以更简单地写成:
create sequence myseq;
还有,不用大写编码。这是 70 年代以来的坏习惯。
我已经创建了数据库,我想在其中自动增加主键。我试图触发它但出现上述错误 这是我对 table:
的描述SQL> desc users
Name Null? Type
----------------------------------------- -------- ----------------------------
USER_ID NOT NULL NUMBER(8)
FIRST_NAME NOT NULL VARCHAR2(50)
LAST_NAME NOT NULL VARCHAR2(50)
CITY VARCHAR2(20)
COUNTRY VARCHAR2(20)
PASSWORD NOT NULL VARCHAR2(16)
EMAIL_ID NOT NULL VARCHAR2(50)
当我尝试触发它时出现错误:
CREATE SEQUENCE SYSTEM.MYSEQ
2 START WITH 1
3 MAXVALUE 99999999
4 MINVALUE 1
5 NOCYCLE
6 CACHE 20
7 NOORDER;
CREATE OR REPLACE TRIGGER TR_USERS BEFORE INSERT ON USERS FOR EACH ROW
2 BEGIN SELECT LPAD(LTRIM(RTRIM(TO_CHAR(MYSEQ.NEXTVAL))),10,'0') INTO :NEW.USER_ID FROM DUAL;
3 /
请帮我解决这个错误。
就 编译 而言,触发器没有任何问题(除了您“忘记”END
的事实)。
SQL> CREATE OR REPLACE TRIGGER TR_USERS
2 BEFORE INSERT ON USERS
3 FOR EACH ROW
4 BEGIN
5 SELECT lpad(ltrim(rtrim(to_char(myseq.nextval))), 10, '0')
6 INTO :new.user_id
7 FROM dual;
8 END;
9 /
Trigger created.
SQL> INSERT INTO USERS (FIRST_NAME) VALUES ('Little');
1 row created.
SQL> SELECT * FROM users;
USER_ID FIRST_NAME LAST_NAE CITY COUNTRY PASSW EMAIL_ID
---------- --------------- ---------- ---------- ---------- ----- --------------------
1 Little
SQL>
但是,如果 USER_ID
是 NUMBER
,那么您的触发器代码就过于复杂了,因为无论您使用这些函数做什么,最终都会得到一个 数。从我的示例中可以看出,USER_ID = 1
.
如果是VARCHAR2
,那么
SQL> TRUNCATE TABLE users;
Table truncated.
SQL> ALTER TABLE USERS MODIFY user_id VARCHAR2(10);
Table altered.
SQL> INSERT INTO USERS (FIRST_NAME) VALUES ('Foot');
1 row created.
SQL> SELECT * FROM users;
USER_ID FIRST_NAME LAST_NAE CITY COUNTRY PASSW EMAIL_ID
---------- --------------- ---------- ---------- ---------- ----- --------------------
0000000002 Foot
SQL>
看出区别了吗?
触发器本来可以更简单(但不是 更 更简单;毕竟你在 10g 上)因为没有什么可以 trim :
SQL> CREATE OR REPLACE TRIGGER TR_USERS
2 BEFORE INSERT ON USERS
3 FOR EACH ROW
4 BEGIN
5 SELECT lpad(to_char(myseq.nextval), 10, '0')
6 INTO :new.user_id
7 FROM dual;
8 END;
9 /
Trigger created.
SQL> INSERT INTO USERS (FIRST_NAME) VALUES ('Krishna');
1 row created.
SQL> SELECT * FROM users;
USER_ID FIRST_NAME LAST_NAE CITY COUNTRY PASSW EMAIL_ID
---------- --------------- ---------- ---------- ---------- ----- --------------------
0000000002 Foot
0000000003 Krishna
SQL>
您遇到错误,因为您缺少触发器的 END
:
CREATE OR REPLACE TRIGGER TR_USERS
BEFORE INSERT ON USERS
FOR EACH ROW
BEGIN
SELECT LPAD(LTRIM(RTRIM(TO_CHAR(MYSEQ.NEXTVAL))),10,'0')
INTO :NEW.USER_ID
FROM DUAL;
END; -- <=== this one
/
顺便说一句,触发器似乎没有多大意义。 LPAD(LTRIM(RTRIM(TO_CHAR(MYSEQ.NEXTVAL))),10,'0')
只是一个混淆的 TO_CHAR(MYSEQ.NEXTVAL, 'FM0000000000')
,但是,当 USERS.USER_ID
是数字时,为什么要创建一个带有前导零的字符串???你把 123 变成 '0000000123' 只是为了将它存储为 123.
除了缺少 end
关键字外,您不需要所有字符格式或 'select from dual'。我只会使用:
create or replace trigger tr_users
before insert on users
for each row
begin
:new.user_id := myseq.nextval;
end;
顺便说一句,你的序列也可以更简单地写成:
create sequence myseq;
还有,不用大写编码。这是 70 年代以来的坏习惯。