Tried to create following trriger:
CREATE TRIGGER EWR.INS_STU
AFTER INSERT ON EWR.STUDENT
FOR EACH ROW
BEGIN
IF ( :NEW.ROLL_NO > 60 ) THEN
INSERT INTO EWR.STUDENT_DIV VALUES ( :NEW.ROLL_NO,'P');
END IF;
IF( :NEW.ROLL_NO < 60)
THEN
INSERT INTO EWR.STUDENT_DIV VALUES (:NEW.ROLL_NO,'F');
END IF;
END
!
But it is giving the following error:
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0104N An unexpected token ":NEW.ROLL_NO > 30 ) THEN INSERT INT" was
found following "H ROW BEGIN IF (". Expected tokens may include:
"". LINE NUMBER=6. SQLSTATE=42601
SQL0104N An unexpected token ":NEW.ROLL_NO > 30 ) THEN
INSERT INT" was found following "H ROW
BEGIN
IF (". Expected tokens may include: "".
Why are you using NEW with the notation as a host variable (:)? You do not need to put the colon before the variable name, because this is a trigger that uses only sql (sql pl).
Also, you have to declare how you are going to reference the new values, defined in the header.
REFERENCING NEW AS N
I recreated your case, and it works for me like this:
db2 "create table ewr.student(roll_no int)"
db2 "create table ewr.student_div(roll_no int, other char(1))"
trigger.sql
CREATE TRIGGER EWR.INS_STU
AFTER INSERT ON EWR.STUDENT
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
IF ( NEW.ROLL_NO > 60 ) THEN
INSERT INTO EWR.STUDENT_DIV VALUES ( NEW.ROLL_NO, 'P' );
END IF;
IF ( NEW.ROLL_NO < 60 ) THEN
INSERT INTO EWR.STUDENT_DIV VALUES ( NEW.ROLL_NO, 'F' );
END IF;
END !
db2 -td! -f trigger.sql
DB20000I The SQL command completed successfully.
I hope this solve your problem.
Related
The following code:
USE `securityMisconfigStealToken`;
-- DELIMITER $$
CREATE PROCEDURE `securityMisconfigStealToken`.`getToken`(IN theUserId VARCHAR(64))
BEGIN
DECLARE tokenExists INT;
COMMIT;
SELECT count(token) FROM `securityMisconfigStealToken`.`tokens` WHERE userId = theUserId INTO tokenExists;
IF (tokenExists < 1) THEN
INSERT INTO tokens (userId, token) VALUES (theUserId, SHA2(CONCAT(RAND(), now()), 256));
COMMIT;
END IF;
SELECT token FROM tokens WHERE userId = theUserId;
END
;
-- $$
Throws the exception:
ERROR 1064 (42000) at line 996: You have an error in your SQL syntax;
check the manual that corresponds to your MariaDB server version for
the right syntax to use near '' at line 3
I am currently using mariaDB version 10.5.12.
The first line of code starts at line 994 and ends at 1008, however the error refers to syntax at line 3. I cannot seem to find at all why this code is throwing an error.
From MariaDB Comment Syntax:
There are 3 supported comment styles in MariaDB:
...
From a '-- ' to the end of a line. The space after the two dashes is required (as in MySQL).
...
This means your delimiter will not be accepted, since it's a comment (And same with -- $$ at the end).
In Postgesql db, I created a table like below zzz_sil6. column b is date datatype.
create table zzz_sil6
(
b date
)
if i execute sql as below with only insert statement, it raise an error due to data type problem. This is the case we expected.
insert into zzz_sil6
select 1;
However, when i executed the insert statement in begin end transaction block, it didnt raise an error due to data type problem.
begin
insert into zzz_sil6
select 1;
commit;
end;
Am i missing about transaction block? I m new to postgresql.
I'm trying to create a simple oracle function which loops over some records and then inserts records for each of those ..
CREATE OR REPLACE FUNCTION addNewRolesToAllGDP
return NUMBER
is dummy number;
BEGIN
FOR applicationId IN (SELECT APPID
FROM GRPAPPLICATIONINSTANCES
where GRPAPPID = (select GRPAPPID
from GRPAPPLICATIONS
where GRPNAME = 'DIGITAL_OFFICE')
AND APPID in (select APPID from APPLICATIONS where REGEXP_LIKE(APPNAME, '[[:digit:]]')))
LOOP
INSERT INTO ROLES (ROLID, ROLNAME, APPID)
VALUES (SEQROLES.nextval,
'INVENTORY_REQUESTER',
applicationId);
INSERT INTO ROLES (ROLID, ROLNAME, APPID)
VALUES (SEQROLES.nextval,
'INVENTORY_OWNER',
applicationId);
INSERT INTO ROLES (ROLID, ROLNAME, APPID)
VALUES (SEQROLES.nextval,
'INVENTORY_ADMIN',
applicationId);
END LOOP;
RETURN 1;
END;
alter function addNewRolesToAllGDP compile;
This statements gives me the following in USER_ERRORS:
PLS-00103: Encountered the symbol "" when expecting one of the following: ( return compress compiled wrapped
I'm not sure if this is the problem, but I notice that you do not have a slash following the END statement of the function. In Oracle tools, without that slash, the statement does not actually get terminated, and the ALTER command is included as part of the same statement. This can cause weird syntax errors.
If this is the problem, fundamentally this question is a duplicate of oracle SQL plus how to end command in SQL file?.
Edited to add As others have said in comments, the same code seems to compile fine for me when I cut-and-paste it from your post. Based on the error and the position where it is reported, my best guess is that at the end of the first line your original source has some invisible character that is causing the parser error.
Used to run this in Intellij which gave me the stated behaviour. After running it from sqlDeveloper it compiled fine.
I got a similar error message for a missing comma in the procedure definition and got compiled after adding the comma.
Procedure definition before fix
PROCEDURE CREATE_WO(p_wo_type IN NUMBER,
p_id IN NUMBER,
p_do_commit IN VARCHAR2 DEFAULT 'Y'
p_return_value OUT VARCHAR2)
IS
BEGIN
...
END;
Error Message
Cause: java.sql.SQLException: ORA-06550: line 8, column 9:
PLS-00103: Encountered the symbol "" when expecting one of the following:
) , * & = - + < / > at in is mod remainder not rem =>
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
Procedure definition after fix, note the comma at the end of p_do_commit
PROCEDURE CREATE_WO(p_wo_type IN NUMBER,
p_id IN NUMBER,
p_do_commit IN VARCHAR2 DEFAULT 'Y',
p_return_value OUT VARCHAR2)
IS
BEGIN
...
END;
I'm learning PL/SQL specifically triggers, and I want to learn how to operate on multiple tables using triggers but I'm having trouble understanding the process. Here's an example:
CREATE TABLE Sess
(code INTEGER NOT NULL,
dateStart DATE NOT NULL,
dateEnd DATE NOT NULL,
CONSTRAINT KeySess PRIMARY KEY(code)
)
CREATE TABLE Ins
(codeIns CHAR(12) NOT NULL,
code INTEGER NOT NULL,
dateIns DATE NOT NULL,
dateAb DATE,
note INTEGER,
CONSTRAINT KeyIns PRIMARY KEY (codeIns, code)
)
1/ I'm trying to build a trigger that will ensure this:
before Insert or Update Ins
dateAb is between dateStart and dateEnd
2/ I want also to ALTER TABLE and lock code, and codeIns in Ins so no one can update them but i don't know the command.
For the first trigger, I tried something like:
CREATE OR REPLACE TRIGGER test
BEFORE INSERT OR UPDATE OF dateAb ON Ins
FOR EACH ROW
DECLARE
start date;
BEGIN
SELECT DISTINCT s.dateStart INTO start
WHERE Ins.code = s.code
IF (:NEW.dateAb < start) THEN
raise_application_error(-20101,'dateAb incorrect');
END IF;
END;
Note: I didn't declare a variable end to check if it's between, my purpose here was to test the correct syntax
Note2: the table are empty.
I had Warning: Trigger created with compilation errors. and 3 errors :
PL/SQL: SQL Statement ignored
4/40 PL/SQL: ORA-00923: key-word FROM absent
9/5 PLS-00103: Encountered the symbol "IF" when expecting one of the
following:
;
And finally like I said I don't know the correct syntax to lock column on table to prevent updates or if it's possible.
I'm learning so if one of you can teach me the correct way to process with my two request, I would apreciate that.
Thank you
Try this:
create or replace trigger test
before insert or update of dateab on ins
for each row
declare
l_sess_start date;
begin
select s.datestart into l_sess_start
from sess s
where s.code = :new.code;
if :new.dateab < l_sess_start then
raise_application_error
( -20101
, 'Start date ' || to_char(:new.dateab,'DD-MON-YYYY') ||
' cannot be before ' || to_char(l_sess_start,'DD-MON-YYYY'));
end if;
end;
Test:
insert into sess values (1, date '2018-04-22', date '2018-04-30');
insert into ins values ('Z', 1, date '2018-04-01', date '2018-04-01', null);
ERROR at line 1:
ORA-20101: Start date 01-APR-2018 cannot be before 22-APR-2018
ORA-06512: at "WILLIAM.TEST", line 10
ORA-04088: error during execution of trigger 'WILLIAM.TEST'
PLS-00103: Encountered the symbol "IF" when expecting one of the
following:
;
This error is because you are missing ; after select statement
This is my sql code:
CREATE OR REPLACE TRIGGER PLACE_NO_TRIGGER
BEFORE INSERT or UPDATE ON UHA_LEASE
FOR EACH ROW BEGIN
INSERT INTO UHA_TEMPVAL SELECT PLACE_NO FROM UHA_RESHALL;
INSERT INTO UHA_TEMPVAL SELECT PLACE_NO FROM UHA_GENERAL;
IF(:NEW.PLACE_NO NOT IN UHA_TEMPVAL.TEMP_VALUE AND :NEW.PLACE_NO IS NOT NULL) THEN
RAISE_APPLICATION_ERROR(-10001, 'PLACE_NO MUST BE IN UHA_RESHALL OR IN UHA_GENERAL OR NULL');
END IF;
DELETE FROM UHA_TEMPVAL;
END;
This is giving these errors:
Error(4,27): PLS-00103: Encountered the symbol "UHA_TEMPVAL" when expecting one of the following: ( The symbol "(" was substituted for "UHA_TEMPVAL" to continue.
Error(4,69): PLS-00103: Encountered the symbol "THEN" when expecting one of the following: ) , and or as The symbol ")" was substituted for "THEN" to continue.
Can someone help me understand why these errors are occurring? It's especially odd because row 4 ends at column 60.
Thanks!
It looks like you're trying to enforce referential integrity from a child table to either of two parent tables. You don't really need to insert and delete from a temporary table; you can count how many rows match in either table:
CREATE OR REPLACE TRIGGER PLACE_NO_TRIGGER
BEFORE INSERT or UPDATE ON UHA_LEASE
FOR EACH ROW
DECLARE
CNT NUMBER;
BEGIN
SELECT COUNT(*)
INTO CNT
FROM (
SELECT PLACE_NO FROM UHA_RESHALL
WHERE PLACE_NO = :NEW.PLACE_NO
UNION ALL
SELECT PLACE_NO FROM UHA_GENERAL
WHERE PLACE_NO = :NEW.PLACE_NO
);
IF :NEW.PLACE_NO IS NOT NULL AND CNT = 0 THEN
RAISE_APPLICATION_ERROR(-10001,
'PLACE_NO MUST BE IN UHA_RESHALL OR IN UHA_GENERAL OR NULL');
END IF;
END;
/
You could choose to only run the query if the :NEW.PLACE_NO is not null but it probably won't make much difference if the columns are indexed.