Search code examples
c#plpgsqlnpgsqlpostgresql-13

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


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 <<:>>


Solution

  • 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).