我发布此内容有两个原因
以下使用 Dapper 和 Npgsql 调用 PostgreSQL 存储过程来插入(传入 null id_inout)或更新记录(id_inout 有值)。
我想了解为什么 PostgreSQL 在调用时需要完整的存储过程签名。
public static int? PO_Save(PurchaseOrder po)
{
int? recordId = null;
using (var cn = new NpgsqlConnection(AppSettings.ConnectionString))
{
if (cn.State != ConnectionState.Open)
cn.Open();
var procName = "CALL po_save(@in_ponumber,@in_deliverydate,@in_bldnum," +
"@in_facname,@in_facnumber,@in_facaddress1,@in_facaddress2,@in_city," +
"@in_state,@in_zip,@in_theme,@id_inout)";
var p = new Dapper.DynamicParameters();
p.Add("@in_ponumber", po.PONumber);
p.Add("@in_deliverydate", po.DeliveryDate);
p.Add("@in_bldnum", po.BldNum);
p.Add("@in_facname", po.FacName);
p.Add("@in_facnumber", po.FacNumber);
p.Add("@in_facaddress1", po.FacAddress1);
p.Add("@in_facaddress2", po.FacAddress2);
p.Add("@in_city", po.City);
p.Add("@in_state", po.State);
p.Add("@in_zip", po.Zip);
p.Add("@in_theme", po.Theme);
p.Add("@id_out", po.POID, null, ParameterDirection.InputOutput);
var res = cn.Execute(procName, p);
recordId = p.Get<int>("@id_inout");
}
return recordId;
}
我想自己找到这个问题的答案,从 Npgsql 7.0 开始,CommandType.StoredProcedure 现在将调用存储过程,而不是像以前那样调用函数。
示例:
await Connection.ExecuteAsync("Foo", commandType: CommandType.StoredProcedure);
将在 Postgresql 中扩展为:
CALL Foo()
您应该能够将
commandType: CommandType.StoredProcedure
传递给 Execute
,例如:
var res = cn.Execute(
"po_save",
new {
in_ponumber = po.PONumber,
in_deliverydate = po.DeliveryDate,
// etc...
},
commandType: CommandType.StoredProcedure,
);
这里是包含这样示例的文档:https://github.com/StackExchange/Dapper/blob/main/Readme.md#stored-procedures