【问题标题】:sp_executesql sets a column to nullsp_executesql 将列设置为空
【发布时间】:2019-10-29 03:57:50
【问题描述】:

我正在尝试在 sp_executesql 中执行一些 SQL。

这是生成的 SQL:

exec sp_executesql
N'declare @RC int
EXECUTE @RC = [dbo].[sp_StoredProcedureName]
  @parameterName
select @RC',
N'@parameterName nvarchar(4000)',
@parameterName=N'TEST'

这是从生成的 SQL 调用的存储过程:

ALTER PROCEDURE [dbo].[sp_StoredProcedureName] (
    @parameterName varchar(4000)
)
with execute as owner
as

DECLARE @returnValue int

BEGIN TRANSACTION 

INSERT INTO [dbo].[TableName]
        (parameterName)
    VALUES
        (@parameterName)
    set @returnValue = IDENT_CURRENT('TableName')
COMMIT

SELECT @returnValue
GO

由于某种原因,parameterName 从未设置。

在 SP 执行后尝试从 TableName 中进行选择时,ParameterName 为 NULL。

我正在使用 MS SQL。 SQL 由 ADO.NET 生成。

【问题讨论】:

  • 不要将sp_ 前缀用于存储过程名称。这是为系统保留的,使用它有一个real impact
  • SELECT @returnValue 返回结果集,而不是返回值。这个存储过程返回了一个单列单行的结果集

标签: sql tsql stored-procedures parameters sp-executesql


【解决方案1】:

评论太长了。

您的存储过程没有返回任何内容,因此返回值为NULL

一般来说,您应该只使用存储过程的返回值作为状态,而不是返回实际数据。

真正的返回值应该通过output参数返回。

此外,我强烈建议为此使用OUTPUT 子句:

ALTER PROCEDURE [dbo].[sp_StoredProcedureName] (
    @parameterName varchar(4000),
    @returnValue int OUTPUT
)
with execute as owner
as
BEGIN
    DECLARE @ids TABLE (id int);

    INSERT INTO [dbo].[TableName] (parameterName)
        OUTPUT id INTO @ids
        VALUES (@parameterName);

    SELECT TOP (1) @returnValue = id  -- only 1 is expected anyway
    FROM @ids;
END;

你可以这样称呼它:

declare @RC int;
declare @parameterName nvarchar(4000);
set @parameterName = N'TEST';

exec [dbo].[sp_StoredProcedureName] @parameterName, @rc int OUTPUT;

动态 SQL 不是必需的。

【讨论】:

  • 然后我会将参数称为 @returnValue 以外的其他名称——这很令人困惑,因为如果客户端代码想要捕获实际返回值,通常必须使用 ReturnValue 伪参数,所以这些看起来是一样的。
  • @JeroenMostert 。 . .我同意这个命名。 OP 为返回的 id 选择了该名称。我只会使用@id
  • 是的,抱歉,这些名称只是出于数据混淆的原因。
  • @GordonLinoff,感谢您的建议,我会考虑以这种方式实现它+1
猜你喜欢
  • 2015-02-28
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多