Exception handling and signaling in SQL/PSM samples

Z PostgreSQL
Skočit na navigaci Skočit na vyhledávání

Signaling exception

-- signaling user exception completly parametrized
CREATE OR REPLACE FUNCTION fx()
RETURNS int AS 
$$
  BEGIN
    SIGNAL SQLSTATE VALUE '11111' 
      SET MESSAGE_TEXT = 'Pavel Stehule',
          DETAIL       = 'a bydlim ve Skalici',
          HINT         = 'obcas take nekde jinde';
    RETURN 1;
 END;
$$ LANGUAGE plpgpsm;

-- signaling knowned exception without additional parameters
CREATE OR REPLACE FUNCTION fx()
RETURNS int AS 
$$
  BEGIN
    SIGNAL SQLSTATE VALUE '42000';
    RETURN 1;
  END;
$$ LANGUAGE plpgpsm;

-- signaling exception via conditional's name
CREATE OR REPLACE FUNCTION fx()
RETURNS int AS 
$$
  BEGIN
    DECLARE my_condition CONDITION FOR SQLSTATE VALUE '00001';
    SIGNAL my_condition;
    RETURN 1;
  END;
$$ LANGUAGE plpgpsm;

-- handling warnings, undo handler
CREATE OR REPLACE FUNCTION fx()
RETURNS void AS
$$
BEGIN
  BEGIN                         
    DECLARE w CONDITION FOR SQLSTATE '01000';
    DECLARE CONTINUE HANDLER FOR w PRINT 'handler';
    DROP TABLE IF EXISTS foo;
    CREATE TABLE foo(a integer);
    PRINT 'A';
    INSERT INTO foo VALUES(10);
    PRINT 'B';
    SIGNAL w;
    BEGIN ATOMIC
      DECLARE UNDO HANDLER FOR w PRINT 'inner handler';
      INSERT INTO foo VALUES(20);
      SIGNAL SQLSTATE '01000';
      INSERT INTO foo VALUES(30);
    END;
    PRINT 'C';
  END;
END;
$$ LANGUAGE plpgpsm;

-- using SQLSTATE variable
CREATE OR REPLACE FUNCTION fog() 
RETURNS void AS 
$$
  BEGIN ATOMIC
    DECLARE SQLSTATE char(5);
    DECLARE CONTINUE HANDLER FOR NOT FOUND PRINT 'Not found', SQLSTATE;
    DECLARE UNDO HANDLER FOR SQLSTATE '33333' PRINT '33333 handled', SQLSTATE;
    SIGNAL SQLSTATE '02002';
    PRINT SQLSTATE;
    SIGNAL SQLSTATE '33333';
    PRINT SQLSTATE; -- no sence
  END;
$$ LANGUAGE plpgpsm;

-- next sample of SQLSTATE
CREATE OR REPLACE FUNCTION foo(OUT SQLSTATE char(5)) AS 
$$
  CASE 1 WHEN 0 THEN PRINT 'something wrong'; END CASE;
$$ LANGUAGE plpgpsm;

-- order specific handler (SQLSTATE, SQLCLASS) before and general handler
CREATE OR REPLACE FUNCTION foo()
RETURNS void AS
$$
  BEGIN
    DECLARE sqlstate char(5);
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION PRINT 'any sql exception', sqlstate;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '33000' PRINT 'class 33', sqlstate;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '33001' PRINT 'exact sqlstate 33001';
    SIGNAL SQLSTATE '33002';
  END;
$$ LANGUAGE plpgpsm;

For level NOTICE use PRINT stmt. For SQLSTATE 01xxx and 02xxx use WARNING and for others without 00xxxx (INFO) use ERROR (fully compliant).