How to display Notice successfull in postgres - postgresql

I want to display in my CMD console, ONLY the success message if my request its OK:
Example :
BEGIN
INSERT / UPDATE .... //request
EXCEPTION
WHEN successful_completion THEN RAISE NOTICE 'INFO : MESSAGE RESQUEST IS OK ';
END;
THIS MY CODE EDIT:
DO $$
BEGIN
BEGIN
UPDATE user set age = 22 , date_inscription = '2018-01-30' where id = 154;
EXCEPTION
WHEN ??? THEN ????
END;
RAISE NOTICE 'INFO : L''age et date inscription ont été mis à jour'; // MESSAGE OK
END;
$$

There is no message successful_completion, but I guess you know that.
If you want to send a notice on error, put it into the exception handler.
If you want to send a notice on success, put the RAISE after the SQL statement in question.
If you want to send a notice no matter what, put the RAISE after the whole block.
An example for the second option:
BEGIN
INSERT ...
RAISE NOTICE 'INFO : MESSAGE REQUEST IS OK ';
EXCEPTION
WHEN OTHERS THEN
/* handle the error */
END;

If you want to prevent having the notice INFO : MESSAGE REQUEST IS OK in case of failure, you should but it just between the INSERT statement and the EXCEPTION block, as here:
CREATE OR REPLACE FUNCTION test_notice (int_id INTEGER) RETURNS integer AS
$do$
BEGIN
INSERT INTO tbl VALUES (int_id);
RAISE NOTICE 'INFO : MESSAGE REQUEST IS OK ';
RETURN 0;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Ignoring error';
RETURN 1;
END;
$do$ LANGUAGE plpgsql;
Here is the DDL for the tbl table:
DROP TABLE IF EXISTS tbl;
CREATE TABLE tbl (id int);
ALTER TABLE tbl ADD CONSTRAINT tbl_pk PRIMARY KEY (id);
And here is a test case, with 1 success, 1 failure and then 1 success:
()=#SELECT test_notice (1);
NOTICE: INFO : MESSAGE REQUEST IS OK
test_notice
-------------
0
(1 row)
()=#SELECT test_notice (1);
NOTICE: Ignoring error
test_notice
-------------
1
(1 row)
()=#SELECT test_notice (2);
NOTICE: INFO : MESSAGE REQUEST IS OK
test_notice
-------------
0
(1 row)

There are 2 other methods available if you insist on actually checking, other than retrieving a row from the processed set. First both Insert and Update set FOUND True if a row was processed and False otherwise. The other is to get the actual number of rows processed via Get Diagnostics. The following block demonstrates both.
do $$
declare rows_processed integer;
begin
insert into users(id, age, date_inscription)
values (154, 20, now()::date)
, (164, 22, now()::date);
get diagnostics rows_processed = row_count;
raise notice '1. After Insert: Found=%, Num of Rows=%', found, rows_processed;
UPDATE users
set age = age+2 , date_inscription = now()::date
where id in (154, 160) ; -- one of two
get diagnostics rows_processed = row_count;
raise notice '2. After Update: Found=%, Num of Rows=%', found, rows_processed;
UPDATE users
set age = 12 ,
date_inscription = now()::date
where id = 205;
get diagnostics rows_processed = row_count;
raise notice '3. After Update (no such id): Found=%, Num of Rows=%', found, rows_processed;
delete from users;
get diagnostics rows_processed = row_count;
raise notice '4. After Delete: Found=%, Num of Rows=%', found, rows_processed;
end;
$$;

Related

how to create triggers function before insert show test message

i have a table
CREATE TABLE test.emp (
empname text,
salary integer,
last_date timestamp,
last_user text
);
and function
CREATE FUNCTION test.emp_stamp() RETURNS trigger AS $emp_stamp$
BEGIN
-- Check that empname and salary are given
IF NEW.empname IS NULL THEN
RAISE EXCEPTION 'empname cannot be null';
END IF;
IF NEW.salary IS NULL THEN
RAISE EXCEPTION '% cannot have null salary', NEW.empname;
END IF;
-- Who works for us when she must pay for it?
IF NEW.salary < 0 THEN
RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;
END IF;
-- Remember who changed the payroll when
NEW.last_date := current_timestamp;
NEW.last_user := current_user;
RETURN NEW;
END;
$emp_stamp$ LANGUAGE plpgsql;
how to show message no need to update the values how can i modify my function
trigger is
CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON test.emp
FOR EACH ROW EXECUTE PROCEDURE test.emp_stamp();
I think all you need to do is 1) make sure it's an update and not an insert (otherwise the reference to old won't make any sense and 2) compare to the existing record. Since Employee name seems to be the PK and the last two fields are only to capture changes, my guess is you only want to test the salary:
-- Who works for us when she must pay for it?
IF NEW.salary < 0 THEN
RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;
elsif TG_OP = 'UPDATE' and new.salary = old.salary then
RAISE EXCEPTION 'salary is already %', NEW.salary;
END IF;
But of course you could also use this for any field. If you wanted to make sure at least one changed, it would be something like this:
elsif TG_OP = 'UPDATE' and
new.salary = old.salary and
new.last_date = old.last_date and
new.last_user = old.last_user then
RAISE EXCEPTION 'Update does not alter any data';
END IF;

Why am I getting a Warning: Trigger created with compilation errors?

This is my first time messing with Triggers in SQL*Plus, and I want to not have more than the max capacity of a movie theater's showing room.
The showtimes gives the max_occupancy. This is what I have:
CREATE OR REPLACE TRIGGER over_capacity
BEFORE INSERT OR UPDATE ON tickets
FOR EACH ROW
WHEN (NEW.SHOWID=OLD.SHOWID)
DECLARE
nope EXCEPTION;
ti SYS_REFCURSOR;
sh SYS_REFCURSOR;
total INT;
max_oc INT;
BEGIN
OPEN sh FOR
SELECT s.max_occupancy FROM showtimes s WHERE NEW.showid=s.showid;
FETCH sh INTO max_oc;
OPEN ti FOR
SELECT COUNT(t.userid) FROM tickets t WHERE t.showid=NEW.showid;
FETCH ti INTO total;
IF total=max_oc THEN
RAISE nope;
END IF;
EXCEPTION
WHEN nope THEN
raise_application_error (-20500, 'AT CAPACITY');
END;
/
You can use just select statements like this:
CREATE OR REPLACE TRIGGER over_capacity
BEFORE INSERT OR UPDATE ON tickets FOR EACH ROW
WHEN (NEW.SHOWID=OLD.SHOWID)
DECLARE
nope EXCEPTION;
total INT;
max_oc INT;
BEGIN
SELECT max_occupancy INTO total FROM showtimes WHERE showid = :new.showid;
SELECT COUNT(userid) INTO max_oc FROM tickets WHERE showid=:new.showid;
IF total=max_oc THEN
RAISE nope;
END IF;
EXCEPTION
WHEN nope THEN
raise_application_error (-20500, 'AT CAPACITY');
END;
/

Exception PostgreSQL

I want to update a column topic in the table abonnement when id_abonnement=3. For this, I want to make an exception when id_abonnement=3 is not exist in database.
I'm trying something like that :
DO $$
BEGIN
BEGIN
update abonnement set topic = 'valeurTopic' where id_abonnement = 3;
EXCEPTION
WHEN "verification of id" THEN RAISE NOTICE 'id=3 not exist';
END;
END;
$$
Any solution please ?!
i find a solution. It's simply like that :
DO $$
BEGIN
BEGIN
IF EXISTS (SELECT * FROM abonnement WHERE id_abonnement=3)
THEN
UPDATE abonnement set topic= 'valeurTopic' WHERE id_abonnement = 3;
RAISE NOTICE 'good operation';
ELSE
RAISE NOTICE 'id = 3 not exist';
END IF;
END;
END;
$$

Execute postgreSQL stored procedure as one transaction

I'm using PostgreSQL 9.3 and I have some stored procedures created which contains several statements. I'm calling this stored procedures in a Java application with the help of a prepared statement.
Now I've read that each statement inside the stored procedure is executed as a transaction, i.e. one commit after each statement. But what I want is to have the whole stored procedure executed as one transaction, i.e. only one commit.
How can I do this? Perhaps deactivating autocommit on the JDBC level?
Well, basically stored procedures are atomic in nature and executed as one transaction.
CREATE TABLE xxx (id int PRIMARY KEY);
CREATE OR REPLACE FUNCTION f() RETURNS void AS $$
DECLARE
len int;
BEGIN
RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
INSERT INTO xxx VALUES (1);
RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
INSERT INTO xxx VALUES (2);
RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
SELECT COUNT(*) FROM xxx INTO len;
RAISE NOTICE 'Number of records: %', len;
RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
-- results in unique constraint violation
UPDATE xxx SET id = 3;
END;
$$ LANGUAGE plpgsql;
Then try invoking f() from psql.
stackoverflow=# show autocommit;
autocommit
------------
on
(1 row)
stackoverflow=# SELECT f();
NOTICE: Transaction ID: 15086
NOTICE: Transaction ID: 15086
NOTICE: Transaction ID: 15086
NOTICE: Number of records: 2
NOTICE: Transaction ID: 15086
ERROR: duplicate key value violates unique constraint "xxx_pkey"
DETAIL: Key (id)=(3) already exists.
CONTEXT: SQL statement "UPDATE xxx SET id = 3"
PL/pgSQL function f() line 20 at SQL statement
stackoverflow=# SELECT * FROM xxx;
id
----
(0 rows)

Testing error within function in PostgreSQL

How to check the error within the function of PostgreSQL?
My try for the same as shown below in the example.
Example:
create or replace function fun_testing(sn int, na text, gen text, ad text, rn int, flag int)
returns int as
$$
begin
if flag = 1 then
insert into testing(ssn,name,gender,address,rno) values(sn,na,gen,ad,rn);
elsif flag = 2 then
update testing
set ssn=sn,
name=na,
gender=gen,
address=ad,
rno = rn
where ssn=sn;
elsif flag =3 then
delete from testing
where ssn =sn;
end if;
if error <> 0 then /* Error Testing */
return(1);
else
return(0);
end if;
end;
$$
language plpgsql;
ERROR: column "error" does not exist
Note: The same if condition(using ##error) works fine with SQL Server but not getting executed in PostgreSQL.
You need a BEGIN ... EXCEPTION ... END block.
create or replace function fun_testing(sn int, na text, gen text, ad text, rn int,
flag int)
returns int as
$$
begin
if flag = 1 then
insert into testing(ssn,name,gender,address,rno) values(sn,na,gen,ad,rn);
elsif flag = 2 then
update testing
set ssn=sn,
name=na,
gender=gen,
address=ad,
rno = rn
where ssn=sn;
elsif flag =3 then
delete from testing
where ssn =sn;
end if;
exception when others then
raise notice 'The transaction is in an uncommittable state. '
'Transaction was rolled back';
raise notice '% %', SQLERRM, SQLSTATE;
end;
$$ language 'plpgsql';