In a testing.psql file have the following script.
do
$$
BEGIN
UPDATE confi set val = 'YES' Where Name ='ISVALIDCUST';
--savepoint 1 here;
perform testUpdateAdjust1(
tname => 'Test1',
custnumber => 'custno1121',
custid => 61,
regid => 'F');
--rollback to 1 here;
--savepoint 2 here;
perform testUpdateAdjust2(
tname => 'Test2',
custnumber => 'custno1122',
custid => 34,
regid => 'T'
);
--rollback to 2 here;
--savepoint 3 here;
perform testUpdateAdjust3(
tname => 'Test3',
custnumber => 'custno1123',
custid => 54,
regid => 'F'
);
--rollback to 3 here;
end $$ language plpgsql;
The requirement is
First update "confi" table.
Then testUpdateAdjust1 execution is completed then Rollback the operations done by testUpdateAdjust1 only.
After testUpdateAdjust2 execution is completed then Rollback the operations done by testUpdateAdjust2 only.
After testUpdateAdjust3 execution is completed then Rollback the operations done by testUpdateAdjust3 only.
After all three functions executed then the UPDATE statement should be rollbacked.
Please help me.
Thanks in advance.
You cannot roll back some of the statements in a transaction and commit the others. It is “all or nothing”.
You can issue a second UPDATE statement that undoes the effect of the first one.
Related
In my trigger I want to throw an exeption, but it is not working properly, got exception. Using DB2 LUW
{0:0} An unexpected token "SQLSTATE '1234'" was found following "
SIGNAL". Expected tokens may include: "<space>".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.28.11
CREATE OR REPLACE TRIGGER "TRG_ABC_DELETE_CHECK"
NO CASCADE BEFORE DELETE ON ABC
REFERENCING OLD AS OLD_OBJ
FOR EACH ROW MODE DB2SQL
BEGIN
SELECT CASE WHEN (SELECT 1 FROM ABC WHERE ID = 2 OR NAME = 'AA' AND OLD_OBJ.TYPE = 2) THEN
SIGNAL SQLSTATE '1234' ('Wrong Parameters');
END FROM SYSIBM.SYSDUMM1;
END
You can't use another statements (like SIGNAL) in the SELECT statement.
Use the RAISE_ERROR function instead to make SELECT raise an exception conditionally.
Or use CASE statement instead of the CASE expression you use in the question.
I'm new to postgresql and would like to ask how to do a transaction using BEGIN, COMMIT and PQexecPrepared. In my program, I have to update many tables before COMMIT. I do understand that we need to use:
1. PQexec(conn,"BEGIN");
2. execute some queries
3. PQexec(conn,"COMMIT");
I had first tried by using PQexecParams, it worked:
PQexec(conn,"BEGIN");
PQexecParams(conn, "INSERT INTO Cars (Id,Name, Price) VALUES ($1,$2,$3)",
3, NULL, parValues, NULL , NULL, 0 );
PQexec(conn,"COMMIT");
However when I had tried by using PQexecPrepared, my table Cars wasn't updated after COMMIT (of course it worked in autocommit mode without BEGIN &COMMIT )
PQexec(conn,"BEGIN");
PQprepare(conn,"teststmt", "INSERT INTO Cars (Id,Name, Price) VALUES ($1,$2,$3)", 3, NULL );
PQexecPrepared(conn, "teststmt", 3, parValues,NULL, NULL,0);
PQexec(conn,"COMMIT");
Do you have any advice in this case?
I was trying to get a job run every business day (MON to SAT) at 6:30am which the Oracle scheduler refused with
ORA-27419 "unable to determine valid execution date from repeat
interval"
I started losing my mind when i discovered the following behaviour:
First, create a dummy job. Note that it has no schedule and is not enabled.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => '"TMP_DUMMY"',
job_type => 'PLSQL_BLOCK',
job_action => 'begin
dbms_lock.sleep(5);
end;',
number_of_arguments => 0,
start_date => NULL,
end_date => NULL,
enabled => FALSE,
auto_drop => FALSE,
comments => 'Test Job');
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => '"TMP_DUMMY"', attribute => 'store_output', value => TRUE);
DBMS_SCHEDULER.SET_ATTRIBUTE( name => '"TMP_DUMMY"', attribute => 'logging_level', value => DBMS_SCHEDULER.LOGGING_OFF);
END;
/
Next step, set a repeat_interval using BYTIME with any execution time which is equal to or less than 02:55 (MI:SS) after the full hour. It does not matter whether this is done with or without the Hour part and for the former option the exact hour does not matter as well.
BEGIN
DBMS_SCHEDULER.set_attribute( name => '"TMP_DUMMY"', attribute => 'repeat_interval', value => 'FREQ=DAILY;BYTIME=010255');
DBMS_SCHEDULER.enable(name=>'"TMP_DUMMY"');
END;
/
This works perfectly fine for me.
Now i want to increase the BYTIME by 1 second to 02:56 (MI:SS)
BEGIN
DBMS_SCHEDULER.set_attribute( name => '"TMP_DUMMY"', attribute => 'repeat_interval', value => 'FREQ=DAILY;BYTIME=010256');
END;
/
Running this attribute change i get
ORA-27470: failed to re-enable "[schema]"."TMP_DUMMY" after making requested change
ORA-27419: unable to determined valid execution date from repeat interval
I have verified this behaviour for all MI:SS combinations:
set serveroutput on
DECLARE
l_rep_interval VARCHAR2(50 CHAR);
BEGIN
FOR mi IN 0..59
LOOP
FOR ss IN 0..59
LOOP
l_rep_interval := 'FREQ=DAILY;BYTIME='||lpad(to_char(mi*100+ss),4,'0');
DBMS_SCHEDULER.set_attribute( name => '"TMP_DUMMY"', attribute => 'repeat_interval', value => l_rep_interval);
DBMS_SCHEDULER.enable(name=>'"TMP_DUMMY"');
DBMS_OUTPUT.PUT_LINE(l_rep_interval);
END LOOP; --end ss
END LOOP; --end mi
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
It is working properly from 00:00 until 02:55 and fails for all other times.
For me this looks like the MI:SS part is treated as a tinyint and higher values cause a type overflow.
Is this a Bug in the scheduler or am i missing something here?
Oracle version is 12c.
I just ran into this same issue. It looks like (from the documentation) that BYTIME is not recognised (even though SQLDeveloper uses it if you look at the SQL tab of the job GUI)
I found that the following works using BYMinute and ByHour
DBMS_SCHEDULER.set_attribute( name => '"TEST"."JOB"', attribute => 'repeat_interval', value => 'FREQ=DAILY;BYHOUR=9;BYMINUTE=30;BYDAY=MON,TUE,WED,THU,FRI,SAT,SUN');
Hope this helps someone.
fl=s.executeUpdate("
insert into demi(rno,subcode,subname,intm,extm,crd,resultdate)
values(
'13JG1A05A0',
'RT22058',
' FREE OPEN SOURCE SOFTWARE(FOSS) LAB ',
'20',
'70',
'2',
'MAY 2015'
)
end where not exists(SELECT * FROM demi WHERE rn0 ='13JG105A0' AND subcode='RT22058')
");
I'm working in jsp with postgresql as backend, my IDE shows error in this statement.
i want to insert a record into db after checking and making sure that no such record already exists
Is this statement correct, or am I trying a garbage code?
Please help, thanks in advance
The reason for your error message is that an INSERT statement does not allow a WHERE clause.
You can only add a where clause to a SELECT statement (or a DELETE or UPDATE statement)
So you would need to get rid of the VALUES clause and use the insert into .. select ... syntax:
insert into demi(rno,subcode,subname,intm,extm,crd,resultdate)
select '13JG1A05A0',
'RT22058',
' FREE OPEN SOURCE SOFTWARE(FOSS) LAB ',
'20',
'70',
'2',
'MAY 2015'
where not exists (SELECT *
FROM demi
WHERE rn0='13JG105A0'
AND subcode='RT22058');
However for the intended use case:
I'm trying to insert a particular record into db if and only if there exists no other record with same rno and subject code columns
there is a better alternative if you have a unique constraint on (rno, subcode) (which you should) - use the on conflict clause:
insert into demi (rno, subcode, subname, intm, extm, crd, resultdate)
values
(
'13JG1A05A0',
'RT22058',
' FREE OPEN SOURCE SOFTWARE(FOSS) LAB ',
'20',
'70',
'2',
'MAY 2015'
)
on conflict (rno, subcode) do nothing;
Again: the on conflict will only work if you have a unique constraint (or index) on those two columns.
Unrelated, but:
you should specify each constant value with a literal matching the underlying data type. '20' is a character constant, 20 would be a number. Ìf intm, extm and crd re numbers, don't provide character values. Also if resultdate is a date column 'MAY 2015' won't work either.
Not sure how
end where not exists(SELECT * FROM demi WHERE rn0 ='13JG105A0' AND subcode='RT22058')
got into your code, but the whole thing is suspicious what do you even want that to do?
Below is the code i am using to create a trigger(before insert):
ALTER TRIGGER "delete_entry_before_inserting" BEFORE INSERT
ORDER 1 ON "XYZ"."ABC"
REFERENCING NEW AS "inserted"
FOR EACH ROW /* WHEN( search_condition ) */
BEGIN
IF EXISTS (select hostname from ABC WHERE hostname = inserted.hostname) THEN
UPDATE ABC
SET days_count = (days_count + 1)
WHERE hostname = inserted.hostname
ROLLBACK TRANSACTION
END IF
END
But the above thing is giving me error as: syntax error near rollback transaction on line 11
what am i doing wrong here?
You are missing a BEGIN TRANSACTION somewhere in your code.
Check this documentation.