我在select:
中有这个case语句CASE ('$5' = '')
WHEN NOT FALSE THEN TRUE
ELSE
ST_DWithin(latlong_g, ST_SetSRID(ST_Point($5::float, $6::float), 4326), $7, false) END
因此,如果给予prepare的参数为空,则case的计算结果为true(对于封闭以及在查询中使用的位置),否则将执行else。
不幸的是,似乎ELSE由pg解析器进行评估,并且它会消息:
ERROR: invalid input syntax for type double precision: ""
有没有办法防止这种错误?
编辑:完整查询以便清晰:
SELECT addritems.*,
St_y(adresse.latlong),
St_x(adresse.latlong)
FROM adresse
inner join addritems
ON addritems.adrcd = adresse.adrcd
AND addritems.plz LIKE Coalesce(Nullif($2, ''), addritems.plz)
AND CASE ( $3 = '' )
WHEN NOT FALSE THEN TRUE
ELSE St_dwithin(latlong_g,
St_setsrid(St_point($3::FLOAT, $4:: FLOAT), 4326),
$5, FALSE)
END
答案 0 :(得分:2)
如何使用 OR:
SELECT addritems.*, St_y(adresse.latlong), St_x(adresse.latlong)
FROM adresse
inner join addritems
ON addritems.adrcd = adresse.adrcd
AND addritems.plz LIKE Coalesce(Nullif($2, ''), addritems.plz)
AND (
$3 = ''
OR St_dwithin(latlong_g,St_setsrid(St_point($3::FLOAT, $4::FLOAT),4326),$5,FALSE)
)
从评论中回答亚历克斯:
原因是:Postgresql 在解析查询时,将 ( 1/0) 视为一个常量,并尝试通过实际潜水数字使其更简单,而如果您将其替换为值不能为的值在解析步骤评估,它将推迟到执行时间。比如将(1/0)替换为(1/floor(random()),查询会成功运行,因为执行时会显示“random()”的值。
SELECT
current_catalog
,current_catalog::text = 'test'
,CASE
WHEN current_catalog::text = 'test' THEN 1 -- division by zero
ELSE 1 / floor(random())
END
注意: floor(random()) 始终为 0,因为 random() 介于 0 和 1 之间。
答案 1 :(得分:0)
我认为你应该像这样编写你的CASE
CASE
WHEN ('$5' = '') THEN NULL -- or -1 some other constant,
-- I guess distance cant be negative.
ELSE ST_DWithin(latlong_g,
ST_SetSRID(ST_Point('$5'::float, '$6'::float), 4326),
$7, false)
END
如果NULL
适合您,也可以使用CASE
CASE
WHEN ('$5' <> '')
THEN ST_DWithin(latlong_g,
ST_SetSRID(ST_Point('$5'::float, '$6'::float), 4326),
$7, false)
-- NO NEED ELSE mean default to NULL.
END
编辑:查询后需要
AND (( $3 = '') OR
( St_dwithin(latlong_g,
St_setsrid(St_point($3::FLOAT, $4::FLOAT), 4326),
$5, FALSE)
))