如何在C#中调用带参数的PostgreSQL存储过程?
在C#中调用带参数的PostgreSQL存储过程的正确方式
问题背景
尝试调用带参数的PostgreSQL存储过程时遇到异常:无参数存储过程可正常调用,但带参数的要么提示存储过程不存在,要么提示列不存在。
表结构
(col1 integer, col2 character varying(20) )
存储过程定义
create procedure proc1 (num int, str varchar(20)) language plpgsql as $$ begin insert into test1 (col1, col2) VALUES (num, str); commit; end;$$;
错误调用方式及异常
错误方式1
using var cmd = new NpgsqlCommand("CALL proc1()", _con); cmd.Parameters.AddWithValue("num", NpgsqlDbType.Integer, 2); cmd.Parameters.AddWithValue("str", NpgsqlDbType.Varchar, "string"); cmd.ExecuteNonQuery();
触发异常:
Npgsql.PostgresException: '42883: procedure proc1() does not exist
POSITION: 6'
错误方式2
将调用语句改为"CALL proc1(num, str)",触发异常:
Npgsql.PostgresException: '42703: column "num" does not exist'
正确解决方法
问题核心在于调用语句的参数占位符使用错误,以下是两种可行的正确调用方式:
方式1:使用@前缀的命名占位符
using var cmd = new NpgsqlCommand("CALL proc1(@num, @str)", _con); cmd.Parameters.AddWithValue("@num", NpgsqlDbType.Integer, 2); cmd.Parameters.AddWithValue("@str", NpgsqlDbType.Varchar, "string"); cmd.ExecuteNonQuery();
方式2:使用:前缀的命名占位符(PostgreSQL原生格式)
using var cmd = new NpgsqlCommand("CALL proc1(:num, :str)", _con); cmd.Parameters.AddWithValue("num", NpgsqlDbType.Integer, 2); cmd.Parameters.AddWithValue("str", NpgsqlDbType.Varchar, "string"); cmd.ExecuteNonQuery();
关键注意点
- 调用时必须在
CALL语句中明确写出参数占位符,不能省略参数位置写proc1(),否则PostgreSQL会匹配无参数的存储过程,导致“不存在”的错误。 - 直接写
num、str会被PostgreSQL解析为表列名,而非参数,因此会触发“列不存在”的异常。 - Npgsql兼容
@参数名和:参数名两种占位符格式,只需保证占位符名称与AddWithValue中指定的参数名一致即可。
内容的提问来源于stack exchange,提问作者user2945260
相关产品推荐
相关产品推荐

