我正在尝试检查一个值是否为null,如果是这样,select null else会转换为numeric,但它会抛出一个错误。这实际上是插入语句的一部分
INSERT into someTable(name,created,power)
SELECT 'xyz',now(),
case when :power ='null' then NULL else cast(:power as numeric) end from abc
我得到的错误是
Error: ERROR: invalid input syntax for type numeric: "null"
:power是一个可以使用java代码赋予任何值的变量。如果我给出null值,则会给出错误。
在代码中,我从java堆栈跟踪中得到以下错误
org.postgresql.util.PSQLException: ERROR: cannot cast type bytea to numeric
答案 0 :(得分:7)
SELECT CASE WHEN 'null' = 'null' THEN NULL ELSE cast('null' AS numeric) END
DO $$
DECLARE
power text := 'null';
BEGIN
PERFORM CASE WHEN power = 'null' THEN NULL ELSE cast(power AS numeric) END;
END;
$$
如果您构建查询字符串,表达式cast('null' AS numeric)
或只是'null'::numeric
始终会引发异常,即使在永不执行的ELSE
块中也是如此,因为它是 invalid input syntax
,并且在语法检查期间引发异常(如错误消息所示),而不是在执行期间引发异常。
显示的CASE
语句只对参数或变量有意义,而不是文字。在汇编查询字符串之后,文字的第二个实例与第一个实例没有任何关联。
对于像这样的动态SQL,您需要检查构建查询字符串之前的值 。或者您使用函数或预准备语句并将值作为参数传递。那也行。
在您的特定情况下,您可以检查应用中的值并构建如下的查询字符串:
INSERT INTO tbl(name, abc_id, created, power)
SELECT 'xyz'
, abc_id
, now()
, <insert_value_of_power_or_NULL_here> -- automatically converted to numeric
FROM abc
您可能有条件地对different approach to INSERT data from a file感兴趣 对于服务器的本地文件,或者使用psql的元命令COPY,使用\copy来获取客户端本地文件。
答案 1 :(得分:5)
如果字段值为null,并且您希望在这种情况下将其映射到某个值,则可以使用coalesce(field_name, 'Some value')
或coalesce(field_name, 123)
。
有关完整文档,请参阅here。
答案 2 :(得分:1)
你需要检查IS运算符,而不是在处理NULL时使用等号:
INSERT into someTable(name,created,power)
SELECT 'xyz',now(),
case when :power IS null then NULL else cast(:power as numeric) end from abc
答案 3 :(得分:0)
INSERT into someTable(name,created,power) SELECT 'xyz',now(),
case :power when 'null' then NULL else :power end::numeric from abc
答案 4 :(得分:0)
我正在尝试做类似的事情,以便更新/插入一些数字值可以为null的记录。 您可以在将变量发送到函数或函数内部之前验证变量,具体取决于传递的值 (对我来说,每次需要验证值时,使用变量优于使用CASE,然后使用CASE)
因此,使用常规比较操作数处理NULL值以查找要更新的记录可以通过将transform_null_equals设置为ON来完成
我希望这有助于某人
CREATE OR REPLACE FUNCTION update_insert_transaction(vcodaccount integer, vcodaccountaux text,
vdescription text, vcodgroup integer)
RETURNS integer AS $$
DECLARE
n integer = 0;
vsql text = 'NULL';
BEGIN
IF vcodaccountaux <> '' THEN
vsql = vcodaccountaux;
END IF;
SET LOCAL transform_null_equals TO ON;
EXECUTE 'UPDATE account_import_conf SET (codaccount, codaccountaux, description, codgroup) =
('||vcodaccount||','||vsql||',trim('||quote_literal(vdescription)||'),'||vcodgroup||')
WHERE codaccount='||vcodaccount||' AND codaccountaux = '||vsql||' RETURNING * ';
GET DIAGNOSTICS n = ROW_COUNT;
IF n = 0 THEN
EXECUTE 'INSERT INTO account_import_conf (codaccount, codaccountaux, description, codgroup)
SELECT '||vcodaccount||','||vsql||' ,trim('||quote_literal(vdescription)||'),'||vcodgroup||';';
END IF;
RETURN n;
END;$$
LANGUAGE plpgsql;