这个问题是关于 Postgresql 8.3 。
我有一个表格,其中的字段包含'lastcontact is null'等条件。在代码中,我想循环遍历这个表,对于每个记录,我想检查'if condition then',就像在这个例子中一样:
FOR myrec IN
SELECT * FROM tabel ORDER BY colorlevel, volgnummer
LOOP
if (myrec.conditie) then
raise notice 'Condition % is true', myrec.conditie;
else
raise notice 'Condition % is false', myrec.conditie;
end if;
END LOOP;
我在这个例子中称为'tabel'的表格:
ID | Conditie | Colorlevel | Volgnummer | Code | Description
1 | lastcontact is null | 1 | 1 | ... | ...
2 | lastchanged is null | 1 | 2 | ... | ...
3 | lastmodified is null | 1 | 3 | ... | ...
我可以做我想要的检查吗?上面的代码导致以下错误:
ERROR: invalid input syntax for type boolean: "lastcontact is null"
包含Erwin功能结果的新栏目
我使用过这个功能:
CREATE OR REPLACE FUNCTION foo(lastcontact timestamptz)
RETURNS void AS
$BODY$
DECLARE
myrec record;
mycond boolean;
BEGIN
FOR myrec IN
SELECT * FROM tabel ORDER BY colorlevel, volgnummer
LOOP
EXECUTE 'SELECT ' || myrec.conditie || ' FROM tabel' INTO mycond;
IF mycond then
RAISE NOTICE 'Condition % is true', myrec.conditie;
ELSE
RAISE NOTICE 'Condition % is false', COALESCE(myrec.conditie, 'NULL');
END IF;
END LOOP;
END;
$BODY$
language 'plpgsql' volatile
cost 100;
我收到此错误:
ERROR: column "lastcontact" does not exist
LINE 1: SELECT lastcontact is null FROM tabel
^
QUERY: SELECT lastcontact is null FROM tabel
CONTEXT: PL/pgSQL function "foo" line 9 at EXECUTE statement1
我试图自己找一个解释,但无济于事。它显然是试图对数据库运行语句,但它应该理解'lastcontact'是作为函数参数给出的变量。
答案 0 :(得分:1)
从评论中我终于认为我明白了。您需要dynamic SQL:
CREATE OR REPLACE FUNCTION foo(lastcontact timestamptz)
RETURNS void AS
$func$
DECLARE
myrec record;
mycond boolean;
BEGIN
FOR myrec IN
SELECT * FROM tabel ORDER BY colorlevel, volgnummer
LOOP
IF myrec.conditie ~~ '%lastcontact %' THEN -- special case for input param
myrec.conditie := replace (myrec.conditie
, 'lastcontact '
, CASE WHEN lastcontact IS NULL THEN 'NULL '
ELSE '''' || lastcontact::text || ''' ' END);
END IF;
EXECUTE 'SELECT ' || myrec.conditie || ' FROM tabel' INTO mycond;
IF mycond then
RAISE NOTICE 'Condition % is true', myrec.conditie;
ELSE
RAISE NOTICE 'Condition % is false', COALESCE(myrec.conditie, 'NULL');
END IF;
END LOOP;
END
$func$ LANGUAGE plpgsql;
但请注意,此设置对于 SQL注入是敞开的。仅使用验证输入。
函数也适用于PostgreSQL 8.3 (还有DO
语句)。
您不能在动态SQL(EXECUTE
语句)中引用参数。您必须将值放入查询字符串中。
在PostgreSQL 8.4或更高版本中,您拥有USING
clause的优质商品。唉,不是8.3版本。如果可以的话,你应该考虑升级。
我为您的旧版本提供了解决方法。您必须特别注意NULL
值。