可以在PostgreSQL 9.4的PL / pgSQL函数中执行IF条件吗?

时间:2018-10-28 15:03:34

标签: postgresql plpgsql

我有这样的工作功能:

DROP FUNCTION org_sbase2_func.mis_sjekk_lovlige_lmkolonner(integer);
CREATE OR REPLACE FUNCTION org_sbase2_func.mis_sjekk_lovlige_lmkolonner(livsm integer)
  RETURNS void AS
$BODY$
DECLARE
  feil text;
  lmrad RECORD;
  colname text;

BEGIN
  -- Test if all mandatory attributes exists
  -- For all rows
  FOR lmrad IN select * from org_sbase2_tmp.ban492lmpol_5_0_kurs where livsmiljo = livsm LOOP
    --For all columns in tmp
    FOR colname IN (select kol_navn from org_sbase2_func.mis_lovlige_kolonner_alle_lm UNION select kol_navn from org_sbase2_func.mis_lovlige_kolonner_lmX where livsmiljo = livsm) LOOP
      --If column exists in tmp and is not null, but the column is not mandatory: ERROR - value must be null
      IF colname IN (SELECT column_name from information_schema.columns WHERE table_schema LIKE 'org_sbase2_tmp' AND table_name LIKE 'ban492lmpol_5_0_kurs') 
         --and colname.value is not null) 
         AND colname in (select kol_navn from org_sbase2_func.mis_lovlige_kolonner_alle_lm UNION select kol_navn from org_sbase2_func.mis_lovlige_kolonner_lmX where livsmiljo != livsm)  THEN
        feil = 'Livsmiljø ' || lmrad.livsmiljo || ' and column ' || colname ||' must be empty, but has value.';
        PERFORM org_sbase2_func.mis_registrer_feil_pa_objekt('lmpol', lmrad.ogc_fid,'ban492',feil,'mis_sjekk_lovlige_lmkolonner');
      END IF;
    END LOOP;
  END LOOP;
  RAISE NOTICE 'Ferdig med mis_sjekk_lovlige_lmkolonner';
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

我使用select org_sbase2_func.mis_sjekk_lovlige_lmkolonner(2);

运行该函数

有效。但是,由于需要包含and lmrad.||colname|| is not null之类的内容,因此需要对其进行修改。我尝试执行。首先(只是为了测试EXECUTE),我使用与上面相同的代码(在测试行中特定列的null为空之前)只是为了尝试获得所有的'正确:

DROP FUNCTION org_sbase2_func.mis_sjekk_lovlige_lmkolonner(integer);
CREATE OR REPLACE FUNCTION org_sbase2_func.mis_sjekk_lovlige_lmkolonner(livsm integer)
  RETURNS void AS
$BODY$
DECLARE
  feil text;
  lmrad RECORD;
  colname text;

BEGIN
  -- Test if all mandatory attributes exists
  -- For all rows
  FOR lmrad IN select * from org_sbase2_tmp.ban492lmpol_5_0_kurs where livsmiljo = livsm LOOP
    --For all columns in tmp
    FOR colname IN (select kol_navn from org_sbase2_func.mis_lovlige_kolonner_alle_lm UNION select kol_navn from org_sbase2_func.mis_lovlige_kolonner_lmX where livsmiljo = livsm) LOOP
      --If column exists in tmp and is not null, but the column is not mandator: ERROR - value must be null
      EXECUTE 'IF '||colname||' IN (SELECT column_name from information_schema.columns WHERE table_schema LIKE ''org_sbase2_tmp'' AND table_name LIKE ''ban492lmpol_5_0_kurs'') --and lmrad.'||colname||' is not null
         AND '||colname||' in (select kol_navn from org_sbase2_func.mis_lovlige_kolonner_alle_lm UNION select kol_navn from org_sbase2_func.mis_lovlige_kolonner_lmX where livsmiljo != livsm)  THEN
        feil = ''Livsmiljø '' || lmrad.livsmiljo || '' og kolonne '' || colname ||'' skulle vært tom, men har verdi'';
        PERFORM org_sbase2_func.mis_registrer_feil_pa_objekt(''lmpol'', lmrad.ogc_fid,''ban492'',feil,''mis_sjekk_lovlige_lmkolonner'');
      END IF;'; 
    END LOOP;
  END LOOP;
  RAISE NOTICE 'Ferdig med mis_sjekk_lovlige_lmkolonner';
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

现在,在运行select org_sbase2_func.mis_sjekk_lovlige_lmkolonner(2);时会引发错误:

ERROR:  syntax error at or near "IF"
LINE 1: IF LDVLAUS302 IN (SELECT column_name from information_schema...
        ^
QUERY:  IF LDVLAUS302 IN (SELECT column_name from information_schema.columns WHERE table_schema LIKE 'org_sbase2_tmp' AND table_name LIKE 'ban492lmpol_5_0_kurs') --and lmrad.LDVLAUS302 is not null
         AND LDVLAUS302 in (select kol_navn from org_sbase2_func.mis_lovlige_kolonner_alle_lm UNION select kol_navn from org_sbase2_func.mis_lovlige_kolonner_lmX where livsmiljo != livsm)  THEN
        feil = 'Livsmiljø ' || lmrad.livsmiljo || ' og kolonne ' || colname ||' skulle vært tom, men har verdi';
        PERFORM org_sbase2_func.mis_registrer_feil_pa_objekt('lmpol', lmrad.ogc_fid,'ban492',feil,'mis_sjekk_lovlige_lmkolonner');
      END IF;
CONTEXT:  PL/pgSQL function org_sbase2_func.mis_sjekk_lovlige_lmkolonner(integer) line 15 at EXECUTE

如果可能的话,我该如何执行IF条件?

2 个答案:

答案 0 :(得分:0)

除了IF/THEN以外,CASE/WHEN中没有SQL语句。该声明记录在9.17. Conditional Expressions一章中。 对于您的情况,更方便的是使用COALESCE,该方法测试一列是否为空,并在这种情况下返回另一列,如postgres文档的同一章中所述。

答案 1 :(得分:0)

由于来自@wildplasser和@ jens-vagts的评论,我设法在函数中重写了查询和测试,使其可以正常工作:

DROP FUNCTION org_sbase2_func.mis_sjekk_lovlige_lmkolonner(integer);
CREATE OR REPLACE FUNCTION org_sbase2_func.mis_sjekk_lovlige_lmkolonner(livsm integer)
  RETURNS void AS
$BODY$
DECLARE
  colname text;
  sporring text;
  feil text;
  i integer;

BEGIN
  --Hvis kolonna ikke fins i tmp, men kolonna er påkrevd (verdi er enten påkrevd eller opsjon): FEIL - egenskapen mangler
  --Test 1: Check if tmp table is missing mandatory columns (attributes) for livsmiljo X
  --For all columns in tmp
  FOR colname IN (SELECT kol_navn FROM org_sbase2_func.mis_lovlige_kolonner_alle_lm UNION SELECT kol_navn FROM org_sbase2_func.mis_lovlige_kolonner_lmX WHERE livsmiljo = livsm) LOOP
    IF colname NOT IN (SELECT column_name FROM information_schema.columns WHERE table_schema LIKE 'org_sbase2_tmp' AND table_name LIKE 'ban492lmpol_5_0_kurs') THEN
      RAISE NOTICE 'Test 1: Kolonne % mangler',colname;
      feil = 'Test 1: Kolonne som er påkrevd for livsmiljø '||livsm||' mangler: '||colname;
      PERFORM org_sbase2_func.mis_registrer_feil_pa_datasett('ban492',feil,'mis_sjekk_lovlige_lmkolonner');
    END IF;
  END LOOP;

  --Using a temporary table to store result from query, deletes the table if it exits before re-creating it
  DROP TABLE IF EXISTS org_sbase2_tmp.tmp_testresultat;
  CREATE UNLOGGED TABLE org_sbase2_tmp.tmp_testresultat (
    testres BOOLEAN
  );

  --Hvis kolonna fins i tmp og er ikke NULL, men kolonna er ikke påkrevd: FEIL - verdi skal være NULL
  --Test 3: Check that irrelevant columns (attributes) have no values (are null)
  --For all columns that doesn't matter for livsmiljo X
  FOR colname IN (SELECT column_name FROM information_schema.columns WHERE table_schema LIKE 'org_sbase2_tmp' AND table_name LIKE 'ban492lmpol_5_0_kurs' AND column_name NOT IN (SELECT kol_navn FROM org_sbase2_func.mis_lovlige_kolonner_alle_lm UNION SELECT kol_navn FROM org_sbase2_func.mis_lovlige_kolonner_lmX WHERE livsmiljo = livsm)) LOOP
    TRUNCATE org_sbase2_tmp.tmp_testresultat;
    sporring = 'INSERT INTO org_sbase2_tmp.tmp_testresultat SELECT '||colname||' is null FROM org_sbase2_tmp.ban492lmpol_5_0_kurs WHERE livsmiljo = '||livsm;
    EXECUTE sporring;
    SELECT count(1) FROM org_sbase2_tmp.tmp_testresultat WHERE testres = false INTO i;
    IF i > 0 THEN
      RAISE NOTICE 'Test 3: % %', i, colname;
      feil = 'Test 3: Kolonne som IKKE er relevant for livsmiljø '||livsm||' har verdi: '||colname;
      PERFORM org_sbase2_func.mis_registrer_feil_pa_datasett('ban492',feil,'mis_sjekk_lovlige_lmkolonner');
    END IF;
  END LOOP;

  RAISE NOTICE 'Ferdig med mis_sjekk_lovlige_lmkolonner';
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;