Как выполнить анонимный блок PL/pgSQL (PostgreSQL 13) из Npgsql 4.1.5.0 на C#
У меня есть анонимный блок 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: синтаксическая ошибка около <<: >>
2 ответа
Решение
Заявление
DO
это оператор на стороне сервера, который не поддерживает параметризацию. Вы не можете передавать какие-либо параметры в
DO
блокировать напрямую. В этом случае вам следует написать функцию или просто использовать
COALESCE
функция:
SELECT COALESCE(MAX("CodigoFactura") + 1, 1) INTO secuencial FROM "Factura";
Внимание - использование идентификаторов, чувствительных к регистру, в SQL - довольно плохой шаблон (очень непрактичный).
По словам @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();