How to execute Anonymous Block PL/pgSQL (PostgreSQL 13) from Npgsql 4.1.5.0 in C#

2.5k Views Asked by At

I have this anonymous block 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;
$$

The anonymous block PL/pgSQL execute from Npgsql like this:

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();

And I have this error:

42601: syntax error at or near <<:>>

2

There are 2 best solutions below

3
Pavel Stehule On BEST ANSWER

The statement DO is server side statement that doesn't support parametrisation. You cannot pass any parameters to DO block directly. For this case you should to write a function or just use a COALESCE function:

SELECT COALESCE(MAX("CodigoFactura") + 1, 1) INTO secuencial FROM "Factura";

Attention - using case sensitive identifiers in SQL is pretty bad pattern (very impractical).

0
Ejrr1085 On

According @Pavel Stehule this is the solution (if someone need a complete solution):

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();