pg_ctl -D ~/cluster_phpbuilder/ -o '-c client_min_messages=panic' restart
psql -t -c "select f_msg('this message is sent to the client');"
robert@laptop:~/tmp$ psql -t -c "select f_msg('this message is sent to the client');"
robert@laptop:~/tmp$
CREATE OR REPLACE FUNCTION f_ex1 (
INOUT my_query text
) AS
$body$
BEGIN
EXECUTE my_query INTO my_query;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'an EXCEPTION is about to be raised';
RAISE EXCEPTION 'NUM:%, DETAILS:%', SQLSTATE, SQLERRM;
END;
$body$
LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION f_ex2 (
in my_query text
) RETURNS VOID AS
$body$
BEGIN
EXECUTE my_query;
EXCEPTION
WHEN duplicate_table THEN
IF SQLERRM ='relation "t1" already exists' THEN
RAISE NOTICE 'trapped table creation for t1';
RAISE NOTICE 'function exits gracefully';
ELSIF SQLERRM = 'relation "t2" already exists' THEN
RAISE NOTICE 'trapped table creation for t2';
RAISE NOTICE 'function exits gracefully';
ELSE
RAISE NOTICE 'another table is being affected: %', SQLERRM;
END IF;
WHEN unique_violation THEN
RAISE NOTICE 'continuing the trap';
RAISE NOTICE 'trapped a unique value violation attempt';
WHEN OTHERS THEN
RAISE NOTICE 'last trap';
RAISE EXCEPTION 'NUM:%, DETAILS:%', SQLSTATE, SQLERRM;
RAISE NOTICE 'this commented is not seen because an EXECEPTION has been raised';
END;
$body$
LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION f_ex3 ()
RETURNS VOID AS
$body$
DECLARE
myrec record;
BEGIN
SELECT * INTO STRICT myrec FROM t1;
RAISE NOTICE 'query completed';
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE EXCEPTION 'no records found';
WHEN TOO_MANY_ROWS THEN
RAISE EXCEPTION 'too many rows';
END;
$body$
LANGUAGE PLPGSQL;
CREATE TABLE t4(x int);
CREATE OR REPLACE FUNCTION f_ex4 ()
RETURNS TRIGGER AS
$body$
BEGIN
IF NEW.X>10 THEN
RAISE EXCEPTION 'transaction interupted, the value is greater than 10, give me another value';
END IF;
RETURN NEW;
END;
$body$
LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS ex_trigger ON t4;
CREATE TRIGGER ex_trigger BEFORE INSERT ON t4 FOR EACH ROW EXECUTE PROCEDURE f_ex4();
robert=# INSERT INTO t4 VALUES(1);
INSERT 0 1
robert=# INSERT INTO t4 VALUES(11);
ERROR: transaction interupted, the value is greater than 10, give me another value
CREATE OR REPLACE FUNCTION f_ex5 ()
RETURNS VOID AS
$body$
BEGIN
CREATE TABLE t5(x int unique);
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'sorry, but table t5 has already been created';
BEGIN
INSERT INTO t5 VALUES(1);
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'sorry, but the value 1 has already been inserted';
END;
END;
$body$
LANGUAGE PLPGSQL;
robert=# select f_ex5();
NOTICE: CREATE TABLE / UNIQUE will create implicit index "t5_x_key" for table "t5"
CONTEXT: SQL statement "CREATE TABLE t5(x int unique)"
PL/pgSQL function "f_ex5" line 2 at SQL statement
robert=# select f_ex5();
NOTICE: sorry, but table t5 has already been created
robert=# select f_ex5();
NOTICE: sorry, but table t5 has already been created
NOTICE: sorry, but the value 1 has already been inserted
CREATE OR REPLACE FUNCTION f_ex6 (
INOUT my_str text
) AS
$body$
DECLARE
BEGIN
-- raising an exception always generates SQLSTATE=P0001
RAISE EXCEPTION '%',my_str;
EXCEPTION
WHEN OTHERS THEN
IF substr(my_str,0,4)='001' THEN
my_str = 'alternate processing for raised EXCEPTION with a custom error code of 001';
ELSIF
substr(my_str,0,4)='002' THEN
my_str = 'alternate processing for raised EXCEPTION with a custom error code of 002';
ELSE
my_str='ERROR CODE: ' || SQLSTATE || ', RETURNED CONDITION (MESSAGE): ' || SQLERRM;
END IF;
END;
$body$
LANGUAGE plpgsql;
robert=# select * from f_ex6('001: my first theoretical error message');
my_str
---------------------------------------------------------------------------
alternate processing for raised EXCEPTION with a custom error code of 001
(1 row)
robert=# select * from f_ex6('002: my second theoretical error message');
my_str
---------------------------------------------------------------------------
alternate processing for raised EXCEPTION with a custom error code of 002
(1 row)
robert=# select * from f_ex6('untrapped error message');
my_str
--------------------------------------------------------------------------
ERROR CODE: P0001, RETURNED CONDITION (MESSAGE): untrapped error message
(1 row)
<?php
$conn = pg_pconnect("host=/tmp user=www password=123 dbname=robert");
if (!$conn) {
echo "connection attempt failed";
exit;
}
$query = "SELECT * FROM f_ex1('select * from xxx')";
$result = pg_query($conn, $query);
if (!$result) {
print "<hr>MSG 2: ".pg_last_notice($conn)."<hr>";
print "<hr>MSG 3: ".pg_last_error($conn)."<hr>";
print "MSG 4: ".pg_result_error($conn);
print "<hr>MSG 5: An exception from postgres has been thrown<hr>";
exit;
}
$row = pg_fetch_row($result);
if (!$result) exit;
print $row[0];
?>
<?php
function exec_qry ($c,$q) {
// the '@' symbol supresses the PHP default error messaging
$result = @pg_query($c,$q);
if (!$result) {
throw new Exception(pg_last_error($c));
} else return $result;
}
function get_qry_row($r) {
$row = pg_fetch_row($r);
if (!$r) {
throw new Exception("can't get a row for the query");
} else return $row[0];
}
$conn = pg_pconnect("host=/tmp user=postgres password=123 dbname=postgres");
if (!$conn) {
echo "connection attempt failed";
exit;
}
$query = array
( "select now()",
"select ''hello world'' ",
"select * from nonexistant_table",
"select ''hello world again'' ",
// this next query fails because t1 has a trigger limiting the max value at 10
"insert into t1 values(123)",
"select ''processing complete'' "
);
foreach ($query as $q) {
try {
print "<hr>".get_qry_row(exec_qry($conn,"select f_ex1('$q')"))."<hr>";
} catch (Exception $e) {
print $e->getMessage();
}
}
print "<br><br>.... <b>place post error trapping processing HERE!</b>";
?>