sql server output参数必须显式声明并带output关键字,调用时也需加output修饰,c#中sqlparameter须设direction=output且value不能为null,执行完结果集消费后才可读取其值。

SQL Server中OUTPUT参数必须显式声明并带OUTPUT关键字
不加OUTPUT修饰的参数,哪怕在过程里赋了值,调用端也拿不到——这是“明明写了SET @x = 1却读到NULL”的最常见原因。
- 定义时必须写
@param_name datatype OUTPUT,比如@total INT OUTPUT - 调用时也必须写
EXEC usp_test @out_val OUTPUT,漏掉OUTPUT就等同于传入一个未初始化的输入参数 - 如果混用输入+输出(如
@cnt INT OUTPUT),调用前仍需先给它赋初值,例如SET @cnt = 0
C#中SqlParameter必须设Direction=Output且Value不能为null
ADO.NET不会自动帮你补默认值,Value字段为空会导致报错:Procedure or function 'xxx' expects parameter '@yyy', which was not supplied.
- 必须显式设置
Direction = ParameterDirection.Output -
Value字段不能留空,哪怕不需要输入值,也要填DBNull.Value、0或string.Empty - 字符类OUTPUT参数(如
NVARCHAR(50))必须指定Size,否则C#读出来只有第一个字符 - 执行完
ExecuteNonQuery()或ExecuteReader()后才能读param.Value,提前读是初始值
有SELECT结果集时,必须先消费完再读OUTPUT参数
只要存储过程中有SELECT语句,OUTPUT参数的值就不是“执行完就立刻可用”的——它要等所有结果集被客户端彻底取走才真正就绪。
- 在C#中,必须用
SqlDataReader调用NextResult()直到返回false,再读Parameters["@x"].Value - 不能只用
ExecuteNonQuery(),否则会跳过结果集,导致连接状态异常、OUTPUT值未更新 - 如果过程返回多个结果集(比如两个
SELECT),不遍历完,OUTPUT可能仍是旧值或DBNull.Value - SSMS执行窗口里看不到OUTPUT值,得靠
SELECT @p1, @p2显式输出,否则容易误判过程是否成功
别把OUTPUT当结果集用,类型和数量都得固定
OUTPUT参数本质是按引用传递的标量,不是容器。想靠@json_out NVARCHAR(MAX) OUTPUT塞JSON回来,等于自己造了个解析脆弱、ORM不认、调试困难的坑。
- OUTPUT只适合已知个数、类型稳定、轻量级的值,比如
@count、@max_id、@status_code - 动态结构(如按月份聚合、行列转换、不确定行数)必须用
SELECT结果集,而不是拼字符串或XML - JDBC不支持
CURSOR、TABLE、TIMESTAMP作为OUTPUT类型,这些也得走结果集 - 最常卡住的地方不是语法,而是判断:该用OUTPUT还是SELECT?一旦选错,前端拿不到数据,重构成本远高于一开始选对










