PostgreSQL ์ €์žฅ ํ•จ์ˆ˜ ์ˆ˜์ค€์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ตฌํ˜„์— ๊ด€ํ•œ ์—ฐ๊ตฌ

์ด ์Šค์ผ€์น˜๋ฅผ ์“ฐ๊ฒŒ ๋œ ์›๋™๋ ฅ์€ ๊ธฐ์‚ฌ์˜€์Šต๋‹ˆ๋‹ค. โ€œ๊ฒฉ๋ฆฌ ๊ธฐ๊ฐ„ ๋™์•ˆ ์ž‘์—…๋Ÿ‰์ด 5๋ฐฐ ์ฆ๊ฐ€ํ–ˆ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.โ€ Lingualeo๊ฐ€ 23๋งŒ ๋ช…์˜ ์‚ฌ์šฉ์ž๋ฅผ ๋ณด์œ ํ•œ PostgreSQL๋กœ ์ „ํ™˜ํ•œ ๋ฐฉ๋ฒ•. 4๋…„ ์ „์— ์ถœํŒ๋œ ๊ธฐ์‚ฌ๋„ ํฅ๋ฏธ๋กœ์› ์Šต๋‹ˆ๋‹ค. MySQL์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ตฌํ˜„.

๊ฐ™์€ ์ƒ๊ฐ์ด ํฅ๋ฏธ๋กœ์›Œ ๋ณด์˜€์Šต๋‹ˆ๋‹ค. "๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ตฌํ˜„".

PostgreSQL ์ €์žฅ ํ•จ์ˆ˜ ์ˆ˜์ค€์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ตฌํ˜„์— ๊ด€ํ•œ ์—ฐ๊ตฌ

๋‚˜๋งŒ ์ƒ๊ฐ๋‚œ ๊ฒŒ ์•„๋‹ˆ์—ˆ๋‹ค.

๋˜ํ•œ ๋ฏธ๋ž˜๋ฅผ ์œ„ํ•ด ์šฐ์„  ๊ตฌํ˜„ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•œ ํฅ๋ฏธ๋กœ์šด ๋ฐœ์ „์„ ๋ณด์กดํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋น„๊ต์  ์ตœ๊ทผ์— ์•„ํ‚คํ…์ฒ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋ฐฑ์—”๋“œ ์ˆ˜์ค€์œผ๋กœ ์ด์ „ํ•˜๊ธฐ ์œ„ํ•œ ์ „๋žต์  ๊ฒฐ์ •์ด ๋‚ด๋ ค์กŒ๋‹ค๋Š” ์ ์„ ๊ณ ๋ คํ•˜๋ฉด ๋”์šฑ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐœ๋ฐœ๋œ ๋ชจ๋“  ๊ฒƒ์€ ๊ณง ๋ˆ„๊ตฌ์—๊ฒŒ๋„ ์“ธ๋ชจ๊ฐ€ ์—†๊ณ  ๋ˆ„๊ตฌ์—๊ฒŒ๋„ ๊ด€์‹ฌ์ด ์—†๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์„ค๋ช…๋œ ๋ฐฉ๋ฒ•์€ ์ผ์ข…์˜ ๋ฐœ๊ฒฌ์ด๋‚˜ ์˜ˆ์™ธ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๋…ธํ•˜์šฐ, ๋ชจ๋“  ๊ฒƒ์ด ๊ณ ์ „์ ์ด๋ฉฐ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.(์˜ˆ๋ฅผ ๋“ค์–ด ์ €๋Š” 20๋…„ ์ „์— Oracle์—์„œ ๋น„์Šทํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.) ๋ชจ๋“  ๊ฒƒ์„ ํ•œ ๊ณณ์— ๋ชจ์œผ๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์ด ๋  ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ. ์‹ค์Šต์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ๋™์ผํ•œ ์•„์ด๋””์–ด๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๋…๋ฆฝ์ ์œผ๋กœ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ธฐ๋…ํ’ˆ์œผ๋กœ ๋ณด๊ด€ํ•ด ๋‘๋Š” ๊ฒƒ๋„ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์ด ์„ธ์ƒ์— ์™„๋ฒฝํ•œ ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํ•˜๊ฒŒ๋„ ์‹ค์ˆ˜์™€ ์˜คํƒ€๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„ํŒ๊ณผ ์˜๊ฒฌ์€ ์ ๊ทน ํ™˜์˜ํ•˜๊ณ  ๊ธฐ๋Œ€ํ•˜๋ฉฐ, ํ•œ ๊ฐ€์ง€ ๋” ์ž‘์€ ์„ธ๋ถ€ ์‚ฌํ•ญ - ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ์ƒ๋žต๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์‹ค์ œ ์ž‘์—… ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ์—ฌ์ „ํžˆ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๊ธฐ์‚ฌ๋Š” ์ผ๋ฐ˜์ ์ธ ๊ฐœ๋…์— ๋Œ€ํ•œ ์Šค์ผ€์น˜์™€ ์„ค๋ช…์ผ ๋ฟ์ด๋ฉฐ ๊ทธ ์ด์ƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ „์ฒด์ ์ธ ๊ทธ๋ฆผ์„ ์ดํ•ดํ•˜๋Š” ๋ฐ ์ถฉ๋ถ„ํ•œ ์„ธ๋ถ€ ์‚ฌํ•ญ์ด ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ๊ฐœ๋…์€ "๋ถ„ํ• ํ•˜์—ฌ ์ •๋ณตํ•˜๊ณ , ์ˆจ๊ธฐ๊ณ  ์†Œ์œ ํ•˜๋ผ"์ž…๋‹ˆ๋‹ค.

์•„์ด๋””์–ด๋Š” ๊ณ ์ „์ ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ๋ณ„๋„์˜ ์Šคํ‚ค๋งˆ, ์ €์žฅ๋œ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ๋ณ„๋„์˜ ์Šคํ‚ค๋งˆ์ž…๋‹ˆ๋‹ค.
ํด๋ผ์ด์–ธํŠธ๋Š” ๋ฐ์ดํ„ฐ์— ์ง์ ‘ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์€ ์ €์žฅ๋œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ˆ˜์‹ ๋œ ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค.

์—ญํ• 

CREATE ROLE store;

CREATE ROLE sys_functions;

CREATE ROLE loc_audit_functions;

CREATE ROLE service_functions;

CREATE ROLE business_functions;

๊ณ„ํš

ํ…Œ์ด๋ธ” ์ €์žฅ ๋ฐฉ์‹

์ฃผ์ œ ์—”ํ„ฐํ‹ฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋Œ€์ƒ ํ…Œ์ด๋ธ”์ž…๋‹ˆ๋‹ค.

CREATE SCHEMA store AUTHORIZATION store ;

์‹œ์Šคํ…œ ๊ธฐ๋Šฅ ๋‹ค์ด์–ด๊ทธ๋žจ

ํŠนํžˆ ํ…Œ์ด๋ธ” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ธฐ๋กํ•˜๋Š” ์‹œ์Šคํ…œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

CREATE SCHEMA sys_functions AUTHORIZATION sys_functions ;

ํ˜„์ง€ ๊ฐ์‚ฌ ์ œ๋„

์ €์žฅ๋œ ํ•จ์ˆ˜ ์‹คํ–‰ ๋ฐ ๋Œ€์ƒ ํ…Œ์ด๋ธ” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๋กœ์ปฌ ๊ฐ์‚ฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํ•จ์ˆ˜ ๋ฐ ํ…Œ์ด๋ธ”์ž…๋‹ˆ๋‹ค.

CREATE SCHEMA loc_audit_functions AUTHORIZATION loc_audit_functions;

์„œ๋น„์Šค ๊ธฐ๋Šฅ ๋‹ค์ด์–ด๊ทธ๋žจ

์„œ๋น„์Šค ๋ฐ DML ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

CREATE SCHEMA service_functions AUTHORIZATION service_functions;

๋น„์ฆˆ๋‹ˆ์Šค ๊ธฐ๋Šฅ ๋‹ค์ด์–ด๊ทธ๋žจ

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ˜ธ์ถœํ•˜๋Š” ์ตœ์ข… ๋น„์ฆˆ๋‹ˆ์Šค ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

CREATE SCHEMA business_functions AUTHORIZATION business_functions;

์•ก์„ธ์Šค ๊ถŒํ•œ

์—ญํ•  - DBA ๋ชจ๋“  ์Šคํ‚ค๋งˆ์— ๋Œ€ํ•œ ์ „์ฒด ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค(DB ์†Œ์œ ์ž ์—ญํ• ๊ณผ ๋ถ„๋ฆฌ๋จ).

CREATE ROLE dba_role;
GRANT store TO dba_role;
GRANT sys_functions TO dba_role;
GRANT loc_audit_functions TO dba_role;
GRANT service_functions TO dba_role;
GRANT business_functions TO dba_role;

์—ญํ•  - USER ํŠน๊ถŒ์ด ์žˆ๋‹ค ์‹คํ–‰ ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค_๊ธฐ๋Šฅ.

CREATE ROLE user_role;

์ฒด๊ณ„ ๊ฐ„ ๊ถŒํ•œ

GRANT
๋ชจ๋“  ํ•จ์ˆ˜๋Š” ์†์„ฑ์œผ๋กœ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์•ˆ ์ •์˜์ž ํ•„์š”ํ•œ ์ง€์นจ ๋ชจ๋“  ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์‹คํ–‰ ์ทจ์†Œโ€ฆ ๊ณต๊ฐœ;

REVOKE EXECUTE ON ALL FUNCTION IN SCHEMA sys_functions FROM public ; 
REVOKE EXECUTE ON ALL FUNCTION IN SCHEMA  loc_audit_functions  FROM public ; 
REVOKE EXECUTE ON ALL FUNCTION IN SCHEMA  service_functions FROM public ; 
REVOKE EXECUTE ON ALL FUNCTION IN SCHEMA  business_functions FROM public ; 

GRANT USAGE ON SCHEMA sys_functions TO dba_role ; 
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA sys_functions TO dba_role ;
GRANT USAGE ON SCHEMA loc_audit_functions  TO dba_role ; 
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA loc_audit_functions  TO dba_role ;
GRANT USAGE ON SCHEMA service_functions TO dba_role ; 
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA service_functions TO dba_role ;
GRANT USAGE ON SCHEMA business_functions TO dba_role ; 
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA business_functions TO dba_role ;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA business_functions TO user_role ;

GRANT ALL PRIVILEGES ON SCHEMA store TO GROUP business_functions ;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA store TO business_functions ;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA store TO business_functions ;

์ด์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ๊ฐ€ ์ค€๋น„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์ฑ„์šฐ๊ธฐ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ€์ƒ ํ…Œ์ด๋ธ”

ํ…Œ์ด๋ธ”์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ๊ฒƒ ์™ธ์— ํŠน๋ณ„ํ•œ ๊ธฐ๋Šฅ์€ ์—†์Šต๋‹ˆ๋‹ค. ์—ฐ์†๋ฌผ ๋ช…์‹œ์ ์œผ๋กœ ์‹œํ€€์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ง€์นจ์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

COMMENT ON ...

์— ๋Œ€ํ•œ ๋Œ“๊ธ€ ๋ชจ๋“  ์˜ˆ์™ธ ์—†์ด ๊ฐ์ฒด.

ํ˜„์ง€๊ฐ์‚ฌ

์ €์žฅ๋œ ํ•จ์ˆ˜์˜ ์‹คํ–‰๊ณผ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ธฐ๋กํ•˜๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ ์„ธ๋ถ€ ์ •๋ณด, ํ˜ธ์ถœ๋œ ๋ชจ๋“ˆ์˜ ๋ ˆ์ด๋ธ”, ์ž…๋ ฅ ๋ฐ ์‹ค์ œ ๊ฐ’์„ ํฌํ•จํ•˜๋Š” ๋กœ์ปฌ ๊ฐ์‚ฌ ํ…Œ์ด๋ธ”์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. JSON ํ˜•์‹์˜ ์ถœ๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค.

์‹œ์Šคํ…œ ๊ธฐ๋Šฅ

๋Œ€์ƒ ํ…Œ์ด๋ธ”์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋กœ๊น…ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํŠธ๋ฆฌ๊ฑฐ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

ํ…œํ”Œ๋ฆฟ - ์‹œ์Šคํ…œ ๊ธฐ๋Šฅ

---------------------------------------------------------
-- INSERT
CREATE OR REPLACE FUNCTION sys_functions.table_insert_log ()
RETURNS TRIGGER AS $$
BEGIN
  PERFORM loc_audit_functions.make_log( ' '||'table' , 'insert' , json_build_object('id', NEW.id)  );
  RETURN NULL ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER table_after_insert AFTER INSERT ON storage.table FOR EACH ROW EXECUTE PROCEDURE sys_functions.table_insert_log();

---------------------------------------------------------
-- UPDATE
CREATE OR REPLACE FUNCTION sys_functions.table_update_log ()
RETURNS TRIGGER AS $$
BEGIN
  IF OLD.column != NEW.column
  THEN
    PERFORM loc_audit_functions.make_log( ' '||'table' , 'update' , json_build_object('OLD.column', OLD.column , 'NEW.column' , NEW.column )  );
  END IF ;
  RETURN NULL ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER table_after_update AFTER UPDATE ON storage.table FOR EACH ROW EXECUTE PROCEDURE sys_functions.table_update_log ();

---------------------------------------------------------
-- DELETE
CREATE OR REPLACE FUNCTION sys_functions.table_delete_log ()
RETURNS TRIGGER AS $$
BEGIN
  PERFORM loc_audit_functions.make_log( ' '||'table' , 'delete' , json_build_object('id', OLD.id )  );
  RETURN NULL ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER table_after_delete AFTER DELETE ON storage.table FOR EACH ROW EXECUTE PROCEDURE sys_functions.table_delete_log ();

์„œ๋น„์Šค ๊ธฐ๋Šฅ

๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ์„œ๋น„์Šค ๋ฐ DML ์ž‘์—…์„ ๊ตฌํ˜„ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํ…œํ”Œ๋ฆฟ - ์„œ๋น„์Šค ๊ธฐ๋Šฅ

--INSERT
--RETURN id OF NEW ROW
CREATE OR REPLACE FUNCTION service_functions.table_insert ( new_column store.table.column%TYPE )
RETURNS integer AS $$
DECLARE
  new_id integer ;
BEGIN
  -- Generate new id
  new_id = nextval('store.table.seq');

  -- Insert into table
  INSERT INTO store.table
  ( 
    id ,
    column
   )
  VALUES
  (
   new_id ,
   new_column
   );

RETURN new_id ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

--DELETE
--RETURN ROW NUMBERS DELETED
CREATE OR REPLACE FUNCTION service_functions.table_delete ( current_id integer ) 
RETURNS integer AS $$
DECLARE
  rows_count integer  ;    
BEGIN
  DELETE FROM store.table WHERE id = current_id; 

  GET DIAGNOSTICS rows_count = ROW_COUNT;                                                                           

  RETURN rows_count ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
 
-- UPDATE DETAILS
-- RETURN ROW NUMBERS UPDATED
CREATE OR REPLACE FUNCTION service_functions.table_update_column 
(
  current_id integer 
  ,new_column store.table.column%TYPE
) 
RETURNS integer AS $$
DECLARE
  rows_count integer  ; 
BEGIN
  UPDATE  store.table
  SET
    column = new_column
  WHERE id = current_id;

  GET DIAGNOSTICS rows_count = ROW_COUNT;                                                                           

  RETURN rows_count ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

์—…๋ฌด ๊ธฐ๋Šฅ

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ˜ธ์ถœํ•˜๋Š” ์ตœ์ข… ๋น„์ฆˆ๋‹ˆ์Šค ๊ธฐ๋Šฅ์„ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ํ•ญ์ƒ ๋Œ์•„์˜ต๋‹ˆ๋‹ค - JSON. ์‹คํ–‰ ์˜ค๋ฅ˜๋ฅผ ๊ฐ€๋กœ์ฑ„์„œ ๊ธฐ๋กํ•˜๋ ค๋ฉด ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์˜ˆ์™ธ.

ํ…œํ”Œ๋ฆฟ - ๋น„์ฆˆ๋‹ˆ์Šค ๊ธฐ๋Šฅ

CREATE OR REPLACE FUNCTION business_functions.business_function_template(
--Input parameters        
 )
RETURNS JSON AS $$
DECLARE
  ------------------------
  --for exception catching
  error_message text ;
  error_json json ;
  result json ;
  ------------------------ 
BEGIN
--LOGGING
  PERFORM loc_audit_functions.make_log
  (
    'business_function_template',
    'STARTED',
    json_build_object
    (
	--IN Parameters
    ) 
   );

  PERFORM business_functions.notice('business_function_template');            

  --START BUSINESS PART
  --END BUSINESS PART

  -- SUCCESFULLY RESULT
  PERFORM business_functions.notice('result');
  PERFORM business_functions.notice(result);

  PERFORM loc_audit_functions.make_log
  (
    'business_function_template',
    'FINISHED', 
    json_build_object( 'result',result )
  );

  RETURN result ;
----------------------------------------------------------------------------------------------------------
-- EXCEPTION CATCHING
EXCEPTION                        
  WHEN OTHERS THEN    
    PERFORM loc_audit_functions.make_log
    (
      'business_function_template',
      'STARTED',
      json_build_object
      (
	--IN Parameters	
      ) , TRUE );

     PERFORM loc_audit_functions.make_log
     (
       'business_function_template',
       ' ERROR',
       json_build_object('SQLSTATE',SQLSTATE ), TRUE 
     );

     PERFORM loc_audit_functions.make_log
     (
       'business_function_template',
       ' ERROR',
       json_build_object('SQLERRM',SQLERRM  ), TRUE 
      );

     GET STACKED DIAGNOSTICS error_message = RETURNED_SQLSTATE ;
     PERFORM loc_audit_functions.make_log
     (
      'business_function_template',
      ' ERROR-RETURNED_SQLSTATE',json_build_object('RETURNED_SQLSTATE',error_message  ), TRUE );

     GET STACKED DIAGNOSTICS error_message = COLUMN_NAME ;
     PERFORM loc_audit_functions.make_log
     (
       'business_function_template',
       ' ERROR-COLUMN_NAME',
       json_build_object('COLUMN_NAME',error_message  ), TRUE );

     GET STACKED DIAGNOSTICS error_message = CONSTRAINT_NAME ;
     PERFORM loc_audit_functions.make_log
     (
      'business_function_template',
      ' ERROR-CONSTRAINT_NAME',
      json_build_object('CONSTRAINT_NAME',error_message  ), TRUE );

     GET STACKED DIAGNOSTICS error_message = PG_DATATYPE_NAME ;
     PERFORM loc_audit_functions.make_log
     (
       'business_function_template',
       ' ERROR-PG_DATATYPE_NAME',
       json_build_object('PG_DATATYPE_NAME',error_message  ), TRUE );

     GET STACKED DIAGNOSTICS error_message = MESSAGE_TEXT ;
     PERFORM loc_audit_functions.make_log
     (
       'business_function_template',
       ' ERROR-MESSAGE_TEXT',json_build_object('MESSAGE_TEXT',error_message  ), TRUE );

     GET STACKED DIAGNOSTICS error_message = SCHEMA_NAME ;
     PERFORM loc_audit_functions.make_log
     (s
       'business_function_template',
       ' ERROR-SCHEMA_NAME',json_build_object('SCHEMA_NAME',error_message  ), TRUE );

     GET STACKED DIAGNOSTICS error_message = PG_EXCEPTION_DETAIL ;
     PERFORM loc_audit_functions.make_log
     (
      'business_function_template',
      ' ERROR-PG_EXCEPTION_DETAIL',
      json_build_object('PG_EXCEPTION_DETAIL',error_message  ), TRUE );

     GET STACKED DIAGNOSTICS error_message = PG_EXCEPTION_HINT ;
     PERFORM loc_audit_functions.make_log
     (
       'business_function_template',
       ' ERROR-PG_EXCEPTION_HINT',json_build_object('PG_EXCEPTION_HINT',error_message  ), TRUE );

     GET STACKED DIAGNOSTICS error_message = PG_EXCEPTION_CONTEXT ;
     PERFORM loc_audit_functions.make_log
     (
      'business_function_template',
      ' ERROR-PG_EXCEPTION_CONTEXT',json_build_object('PG_EXCEPTION_CONTEXT',error_message  ), TRUE );                                      

    RAISE WARNING 'ALARM: %' , SQLERRM ;

    SELECT json_build_object
    (
      'isError' , TRUE ,
      'errorMsg' , SQLERRM
     ) INTO error_json ;

  RETURN  error_json ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

ํ•ฉ๊ณ„

์ „์ฒด์ ์ธ ๊ทธ๋ฆผ์„ ์„ค๋ช…ํ•˜์ž๋ฉด ์ด ์ •๋„๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์„ธ๋ถ€ ์‚ฌํ•ญ๊ณผ ๊ฒฐ๊ณผ์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ๋ถ„์ด ๊ณ„์‹œ๋‹ค๋ฉด ๋Œ“๊ธ€์„ ๋‹ฌ์•„ ์ฃผ์‹œ๋ฉด ์‚ฌ์ง„์— ์ถ”๊ฐ€ ์ž‘์—…์„ ์ถ”๊ฐ€ํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

PS

๋‹จ์ˆœ ์˜ค๋ฅ˜ ๋กœ๊น… - ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜ ์œ ํ˜•

-[ RECORD 1 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1072
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          | STARTED
jsonb_pretty    | {
                |     "dko": {
                |         "id": 4,
                |         "type": "Type1",                                                                                                                                                                                            
                |         "title": "CREATED BY addKD",
                |         "Weight": 10,
                |         "Tr": "300",
                |         "reduction": 10,
                |         "isTrud": "TRUE",
                |         "description": "decription",
                |         "lowerTr": "100",
                |         "measurement": "measurement1",
                |         "methodology": "m1",                                                                                                                                                                                           
                |         "passportUrl": "files",
                |         "upperTr": "200",
                |         "weightingFactor": 100.123,
                |         "actualTrValue": null,
                |         "upperTrCalcNumber": "120"
                |     },
                |     "CardId": 3
                | }
-[ RECORD 2 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1073
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR
jsonb_pretty    | {
                |     "SQLSTATE": "22P02"
                | }
-[ RECORD 3 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1074
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR
jsonb_pretty    | {
                |     "SQLERRM": "invalid input syntax for type numeric: "null""
                | }
-[ RECORD 4 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1075
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-RETURNED_SQLSTATE
jsonb_pretty    | {
                |     "RETURNED_SQLSTATE": "22P02"
                | }
-[ RECORD 5 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1076
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-COLUMN_NAME
jsonb_pretty    | {
                |     "COLUMN_NAME": ""
                | }

-[ RECORD 6 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1077
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-CONSTRAINT_NAME
jsonb_pretty    | {
                |     "CONSTRAINT_NAME": ""
                | }
-[ RECORD 7 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1078
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-PG_DATATYPE_NAME
jsonb_pretty    | {
                |     "PG_DATATYPE_NAME": ""
                | }
-[ RECORD 8 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1079
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-MESSAGE_TEXT
jsonb_pretty    | {
                |     "MESSAGE_TEXT": "invalid input syntax for type numeric: "null""
                | }
-[ RECORD 9 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1080
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-SCHEMA_NAME
jsonb_pretty    | {
                |     "SCHEMA_NAME": ""
                | }
-[ RECORD 10 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1081
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-PG_EXCEPTION_DETAIL
jsonb_pretty    | {
                |     "PG_EXCEPTION_DETAIL": ""
                | }
-[ RECORD 11 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1082
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-PG_EXCEPTION_HINT
jsonb_pretty    | {
                |     "PG_EXCEPTION_HINT": ""
                | }
-[ RECORD 12 ]-
date_trunc      | 2020-08-19 13:15:46
id              | 1083
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-PG_EXCEPTION_CONTEXT
jsonb_pretty    | {
usename         | emp1
log_module      | addKD
log_module_hash | 0b4c1529a89af3ddf6af3821dc790e8a
status          |  ERROR-MESSAGE_TEXT
jsonb_pretty    | {
                |     "MESSAGE_TEXT": "invalid input syntax for type numeric: "null""
                | }

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€