如何在 C# 中从 Npgsql 4.1.5.0 执行匿名块 PL/pgSQL (PostgreSQL 13)
Posted
技术标签:
【中文标题】如何在 C# 中从 Npgsql 4.1.5.0 执行匿名块 PL/pgSQL (PostgreSQL 13)【英文标题】:How to execute Anonymous Block PL/pgSQL (PostgreSQL 13) from Npgsql 4.1.5.0 in C# 【发布时间】:2021-02-01 03:32:54 【问题描述】:我有这个匿名块 PL/pgSQL:
DO
$$
DECLARE secuencial INT;
BEGIN
SELECT MAX("CodigoFactura") + 1 INTO secuencial FROM "Factura";
IF secuencial IS NULL THEN
secuencial := 1;
END IF;
RAISE NOTICE '%', secuencial;
END;
$$
匿名块 PL/pgSQL 从 Npgsql 执行如下:
NpgsqlConnection npgsqlConnection = new NpgsqlConnection("Server=127.0.0.1;Port=5432;Database=myBase;User Id=user;Password=password;");
npgsqlConnection.Open();
string sentencialSQL = "DO $$ BEGIN SELECT MAX(\"CodigoFactura\") + 1 INTO :v_secuencial FROM \"Factura\"; IF :v_secuencial is NULL THEN :v_secuencial := 1; END IF; END; $$";
NpgsqlCommand npgsqlCommand = new NpgsqlCommand(sentencialSQL, npgsqlConnection);
// ===============================
NpgsqlParameter npgsqlParameter1 = new NpgsqlParameter();
npgsqlParameter1.ParameterName = ":v_secuencial";
npgsqlParameter1.Value = 0;
npgsqlParameter1.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Integer;
npgsqlParameter1.Direction = ParameterDirection.Output;
npgsqlCommand.Parameters.Add(npgsqlParameter1);
// ===============================
npgsqlCommand.CommandType = CommandType.Text;
npgsqlCommand.ExecuteNonQuery();
npgsqlConnection.Close();
我有这个错误:
42601:>
处或附近的语法错误
【问题讨论】:
你读过github.com/npgsql/npgsql/issues/629吗? 【参考方案1】:语句DO
是不支持参数化的服务器端语句。您不能将任何参数直接传递给DO
块。对于这种情况,您应该编写一个函数或只使用 COALESCE
函数:
SELECT COALESCE(MAX("CodigoFactura") + 1, 1) INTO secuencial FROM "Factura";
注意 - 在 SQL 中使用区分大小写的标识符是非常糟糕的模式(非常不切实际)。
【讨论】:
谢谢,这就是解决方案,我需要做一些改变,但是工作。是的,SQL 中的敏感标识符非常糟糕,但这只是一个测试,我在 SQL 中的名称中使用大写。 @Ejrr1085 - Postgres 更喜欢小写标识符 哦,我明白了,好的,谢谢你的建议,我会记住的:)【参考方案2】:根据@Pavel Stehule,这是解决方案(如果有人需要完整的解决方案):
NpgsqlConnection npgsqlConnection = new NpgsqlConnection("Server=127.0.0.1;Port=5432;Database=myBase;User Id=user;Password=password;");
npgsqlConnection.Open();
string sentencialSQL = "SELECT COALESCE(MAX(\"CodigoFactura\") + 1, 1) FROM \"Factura\";";
NpgsqlCommand npgsqlCommand = new NpgsqlCommand(sentencialSQL, npgsqlConnection);
// ===============================
npgsqlCommand.CommandType = CommandType.Text;
object secuencial = npgsqlCommand.ExecuteScalar();
npgsqlConnection.Close();
【讨论】:
以上是关于如何在 C# 中从 Npgsql 4.1.5.0 执行匿名块 PL/pgSQL (PostgreSQL 13)的主要内容,如果未能解决你的问题,请参考以下文章
尝试在同一连接中运行多个命令时 C# Winforms Npgsql 3.0.5“操作已在进行中”错误