【问题标题】:Npgsql AddWithValue doesn't work with transactionNpgsql AddWithValue 不适用于事务
【发布时间】:2020-03-30 06:38:47
【问题描述】:

我正在尝试使用 Npgsql 中的事务执行查询,因为它使代码明显更清晰,并且与其他纯 SQL 系统中的查询更加一致。但是我在以下代码中收到错误Npgsql.PostgresException: 42703: column "_hash" does not exist

var cmd = new NpgsqlCommand(@"
do
$do$
begin
    if ((select count(1) from components where hash = @_hash) = 0) then
        insert into components (hash, name) values (@_hash, @_name);
    end if;
end
$do$", db); // db is NpgsqlConnection connection
cmd.Parameters.AddWithValue("_hash", "00000000-0000-0000-0000-000000000000");
cmd.Parameters.AddWithValue("_name", "t_test");
cmd.ExecuteNonQuery(); // error on this line

由于某种原因,以下内容确实有效,这让我认为这是事务中 AddWithValue 的问题

硬编码值;

var cmd = new NpgsqlCommand(@"
do
$do$
begin
    if ((select count(1) from components where hash = '00000000-0000-0000-0000-000000000000') = 0) then
        insert into components (hash, name) values ('00000000-0000-0000-0000-000000000000', 't_test');
    end if;
end
$do$", db);
cmd.ExecuteNonQuery();

摆脱交易

var cmd = new NpgsqlCommand("insert into components (hash, name) values (@_hash, @_name);", db)
cmd.Parameters.AddWithValue("_hash", "00000000-0000-0000-0000-000000000000");
cmd.Parameters.AddWithValue("_name", "t_test");
cmd.ExecuteNonQuery();

是什么导致了这个问题,如何解决?

注意:我可以运行在 JetBrains DataGrip 等数据库管理器中失败的查询,因此查询不会出现格式错误。

【问题讨论】:

  • 你为什么不用insert into ... where not exists ..

标签: c# sql postgresql npgsql


【解决方案1】:

您不能将参数传递给匿名 do 块。它与 npgsql 无关,但与 Postgres 相关。

doc 说:

代码块被视为函数的主体 没有参数,返回无效。它被解析并执行一个 时间。

【讨论】:

  • 谢谢!只是为了将来的参考,由于这个限制,我做了(轻度)不安全的解决方法,在 NpgsqlCommand 上创建一个扩展方法,它只是用一些逻辑进行查找和替换,以检测类型并正确格式化以模拟功能。
  • 对于这个特定的例子,upsertON CONFLICT DO NOTHING 可以很好地工作,并且它在单个事务中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 2015-05-17
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多