Возможно ли выполнить IF-условие в функции PL / pgSQL в PostgreSQL 9.4? - PullRequest
0 голосов
/ 28 октября 2018

У меня есть такая рабочая функция:

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.Для начала (просто для проверки EXECUTE) я использую тот же код, что и выше (перед тем, как включить проверку значения равным нулю для определенного столбца в строке), просто чтобы попытаться получить все «правильные»:

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 голосов
/ 29 октября 2018

Благодаря комментариям @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;
0 голосов
/ 28 октября 2018

В postgres вообще нет оператора IF/THEN, кроме CASE/WHEN, как обычно в SQL.Заявление задокументировано в главе 9.17.Условные выражения .Еще более удобным для вашего случая может быть использование COALESCE, который проверяет столбец на нулевое значение и возвращает другой столбец в этом случае, как описано в той же главе документации postgres.

...