我在使用RPostgres和RPostgreSQL作为INSERT参数查询传递NULL时遇到问题:
在PostgreSQL中:
create table foo (ival int, tval text, bval bytea);
在R:
这有效:
res <- dbSendQuery(con, "INSERT INTO foo VALUES($1, $2, $3)",
params=list(ival=1,
tval= 'not quite null',
bval=charToRaw('asdf')
)
)
但这会引发错误:
res <- dbSendQuery(con, "INSERT INTO foo VALUES($1, $2, $3)",
params=list(ival=NULL,
tval= 'not quite null',
bval=charToRaw('asdf')
)
)
使用RPostgres,错误信息为:
错误:期待字符串
在RPostgreSQL下,错误是:
Error in postgresqlExecStatement(conn, statement, ...) : RS-DBI driver: (could not Retrieve the result : ERROR: invalid input syntax for integer: "NULL" )
代替NA对我来说没问题,但它不是一个解决方案 - 一个字面上的&#39; NA&#39;被写入数据库。
使用例如整数(0)给出相同的&#34;期望一个字符串&#34;消息。
答案 0 :(得分:3)
这里有一个选项来解决不知道如何在R中表达PostgresSQL pacakge能够成功翻译的NULL
值的问题,就是根本不指定你想要的值为{{ 1}}在数据库中。
所以在你的例子中你可以使用它:
NULL
当您希望res <- dbSendQuery(con, "INSERT INTO foo (col2, col3) VALUES($1, $2)",
params=list(tval = 'not quite null',
bval = charToRaw('asdf')
)
)
拥有col1
值时。这当然假设您的表中的NULL
可以为空,这可能不是这种情况。
答案 1 :(得分:2)
谢谢大家的帮助。蒂姆的答案很好,我用它来捕捉整数值。我为其余部分采用了不同的路线,在PostgreSQL中编写了一个函数来处理大部分内容。它看起来大致如下:
CREATE OR REPLACE FUNCTION add_stuff(ii integer, tt text, bb bytea)
RETURNS integer
AS
$$
DECLARE
bb_comp bytea;
rows integer;
BEGIN
bb_comp = convert_to('NA', 'UTF8'); -- my database is in UTF8.
-- front-end catches ii is NA; RPostgres blows up
-- trying to convert 'NA' to integer.
tt = nullif(tt, 'NA');
bb = nullif(bb, bb_comp);
INSERT INTO foo VALUES (ii, tt, bb);
GET DIAGNOSTICS rows = ROW_COUNT;
RETURN rows;
END;
$$
LANGUAGE plpgsql VOLATILE;
现在来看看RPostgres源代码,看看是否有一种简单的方法可以让它更容易处理NULL / NA。希望它失踪,因为没有人想到它,不是因为它超级棘手。 :)
这将导致&#34;错误&#34;回答是否有人试图按字面意思写出&#39; NA&#39;进入数据库并指除NULL / NA以外的其他东西(例如NA =&#34; North America&#34;);鉴于我们的用例,这似乎不太可能。我们会在六个月内看到。
答案 2 :(得分:2)
您可以直接在insert语句中使用NULLIF
:
res <- dbSendQuery(con, "INSERT INTO foo VALUES(NULLIF($1, 'NULL')::integer, $2, $3)",
params=list(ival=NULL,
tval= 'not quite null',
bval=charToRaw('asdf')
)
)
也适用于NA
。