问题描述
我有这个具有IN char参数和INOUT游标参数的存储过程:
CREATE OR REPLACE PROCEDURE SP_ObtenerFacturaPorNombreCliente(IN p_nombreCliente CHAR,INOUT p_cursorFacturas REFCURSOR)
LANGUAGE PLPGsql
AS
$$
BEGIN
OPEN p_cursorFacturas FOR
SELECT "CodigoFactura","NombreCliente","DireccionCliente","TelefonoCliente","Fecha","SubTotal","Iva","ValorIva","Total","Geografico","Geometrico" FROM "Factura"
WHERE "NombreCliente" = p_nombreCliente
ORDER BY "CodigoFactura";
END
$$
NpgsqlConnection npgsqlConnection = new NpgsqlConnection("Server=127.0.0.1;Port=5432;Database=mybase;User Id=user;Password=password;");
npgsqlConnection.open();
npgsqlConnection.TypeMapper.UseNetTopologySuite();
string sentencialsql = "CALL SP_ObtenerFacturaPorNombreCliente(:p_nombreCliente,:p_cursorFacturas);";
NpgsqlCommand npgsqlCommand = new NpgsqlCommand(sentencialsql,npgsqlConnection);
// ===============================
NpgsqlParameter npgsqlParameter1 = new NpgsqlParameter();
npgsqlParameter1.ParameterName = ":p_nombreCliente";
npgsqlParameter1.Value = "Perico de los palotes";
npgsqlParameter1.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text;
npgsqlParameter1.Direction = ParameterDirection.Input;
npgsqlCommand.Parameters.Add(npgsqlParameter1);
// -------------------
NpgsqlParameter npgsqlParameter2 = new NpgsqlParameter();
npgsqlParameter2.ParameterName = ":p_cursorFacturas";
npgsqlParameter2.Value = string.Empty;
npgsqlParameter2.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Refcursor;
npgsqlParameter2.Direction = ParameterDirection.InputOutput;
npgsqlCommand.Parameters.Add(npgsqlParameter2);
// ===============================
npgsqlCommand.CommandType = CommandType.Text; // CommandType.StoredProcedure is with Function
NpgsqlDataReader npgsqlDataReader = npgsqlCommand.ExecuteReader();
使用:npgsqlParameter2.Value = string.Empty;
我遇到此错误:
42601:在>或附近的语法错误
使用:npgsqlParameter2.Value = null;
我遇到此错误:
必须设置参数:p_cursorFacturas
更新:
根据@madreflection的建议,我将null
更改为dbnull.Value
,但呼叫将npgsqlParameter2
更改为“ ”
NpgsqlConnection npgsqlConnection = new NpgsqlConnection("Server=127.0.0.1;Port=5432;Database=mybase;User Id=user;Password=password;");
npgsqlConnection.open();
npgsqlConnection.TypeMapper.UseNetTopologySuite();
string sentencialsql = "CALL SP_ObtenerFacturaPorNombreCliente(:p_nombreCliente,npgsqlConnection);
// ===============================
NpgsqlParameter npgsqlParameter1 = new NpgsqlParameter();
npgsqlParameter1.ParameterName = ":p_nombreCliente";
npgsqlParameter1.Value = "Perico de los palotes";
npgsqlParameter1.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text;
npgsqlParameter1.Direction = ParameterDirection.Input;
npgsqlCommand.Parameters.Add(npgsqlParameter1);
// -------------------
NpgsqlParameter npgsqlParameter2 = new NpgsqlParameter();
npgsqlParameter2.ParameterName = ":p_cursorFacturas";
npgsqlParameter2.Value = dbnull.Value;
npgsqlParameter2.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Refcursor;
npgsqlParameter2.Direction = ParameterDirection.InputOutput;
npgsqlCommand.Parameters.Add(npgsqlParameter2);
// ===============================
npgsqlCommand.CommandType = CommandType.Text; // CommandType.StoredProcedure is with Function
NpgsqlDataReader npgsqlDataReader = npgsqlCommand.ExecuteReader();
解决方法
好的,我想通了。这篇文章对我帮助很大。这是其他人的答案。
//transaction is needed to keep unnamed portal 1
var transaction = npgsqlConnection.BeginTransaction();
//create the command and add all the parameters,command type,etc
...
npgsqlCommand.CommandType = CommandType.Text;
npgsqlCommand.CommandText = "call your_procedure(:parameters)";
//execute the original procedure with ExecuteNonQuery
npgsqlCommand.ExecuteNonQuery();
//change the command text and execute the reader
npgsqlCommand.CommandText = "fetch all in \"<unnamed portal 1>\"";
var npgsqlDataReader = npgsqlCommand.ExecuteReader();
while (reader.Read())
{
// do whatever is needed to extract the data
}
//clean up
transaction.Commit();
npgsqlConnection.Close();