You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Npgsql调用PostgreSQL存储过程提示‘procedure does not exist’求助

解决Npgsql调用PostgreSQL存储过程报错42883的问题

错误42883: procedure shipment_status.updatefilelocation() does not exist的核心原因是你调用的是无参版本的存储过程,但实际创建的是带4个参数的版本,PostgreSQL无法匹配到对应的存储过程签名。以下是具体修复方案:

修复步骤

1. 修正CALL语句,匹配存储过程参数签名

你的C#代码中CALL shipment_status.updatefilelocation()是无参调用,但存储过程需要4个参数,必须在CALL语句中明确参数占位符,两种写法可选:

方式一:位置占位符(按参数顺序匹配)

var cmd = new NpgsqlCommand("CALL shipment_status.updatefilelocation($1, $2, $3, $4)", con);

方式二:命名参数(更清晰,避免顺序错误)

var cmd = new NpgsqlCommand("CALL shipment_status.updatefilelocation(ids_to_update => $1, files_to_update => $2, start_with => $3, end_with => $4)", con);

2. 确保参数传递准确

你的参数添加顺序是正确的(uuid数组 → text数组 → int → int),可以显式指定参数名称增强可读性:

cmd.Parameters.AddWithValue("ids_to_update", NpgsqlDbType.Array | NpgsqlDbType.Uuid, rfi.Ids.ToArray());
cmd.Parameters.AddWithValue("files_to_update", NpgsqlDbType.Array | NpgsqlDbType.Text, rfi.RawDataStorageLinks.ToArray());
cmd.Parameters.AddWithValue("start_with", NpgsqlDbType.Integer, 0);
cmd.Parameters.AddWithValue("end_with", NpgsqlDbType.Integer, rfi.Ids.Count - 1);

3. 移除不必要的.ToLower()调用

PostgreSQL对未加引号的小写标识符不区分大小写,你的存储过程名称是小写的,无需将CALL语句转成小写,避免潜在的意外问题。

4. 验证权限与Schema可见性

确保执行代码的数据库用户拥有shipment_status Schema的访问权限,以及调用该存储过程的权限,可通过以下SQL配置:

GRANT USAGE ON SCHEMA shipment_status TO your_db_user;
GRANT EXECUTE ON PROCEDURE shipment_status.updatefilelocation(uuid[], text[], integer, integer) TO your_db_user;

完整修复后的C#代码示例

NpgsqlConnection? con = null;

try
{
    RawFileInfo rfi = CreateRawFileInfo(blobData);

    if (rfi == null || rfi.Ids.Count == 0) 
        return;

    con = new NpgsqlConnection(postgresConnection);
    con.Open();

    var cmd = new NpgsqlCommand("CALL shipment_status.updatefilelocation(ids_to_update => $1, files_to_update => $2, start_with => $3, end_with => $4)", con);
    cmd.Parameters.AddWithValue("ids_to_update", NpgsqlDbType.Array | NpgsqlDbType.Uuid, rfi.Ids.ToArray());
    cmd.Parameters.AddWithValue("files_to_update", NpgsqlDbType.Array | NpgsqlDbType.Text, rfi.RawDataStorageLinks.ToArray());
    cmd.Parameters.AddWithValue("start_with", NpgsqlDbType.Integer, 0);
    cmd.Parameters.AddWithValue("end_with", NpgsqlDbType.Integer, rfi.Ids.Count - 1);

    int result = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
    // 补充你的异常处理逻辑
}
finally
{
    con?.Close();
}

额外注意点

存储过程中的COMMIT:如果你的C#代码默认使用自动提交模式,存储过程内的COMMIT会正常执行;但如果代码中显式开启了事务,存储过程内的COMMIT会抛出错误,此时需要移除存储过程中的COMMIT,由应用层统一控制事务。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:05:38