【问题标题】:How to assign an exec result to a sql variable?如何将 exec 结果分配给 sql 变量?
【发布时间】:2022-03-09 04:34:22
【问题描述】:

如何将 exec 调用的结果分配给 SQL 中的变量?我有一个名为up_GetBusinessDay 的存储过程,它返回一个日期。

你可以这样做吗:

exec @PreviousBusinessDay = dbo.up_GetBusinessDay @Date, -1

【问题讨论】:

    标签: sql sql-server tsql stored-procedures


    【解决方案1】:

    我总是使用返回值来传回错误状态。如果您需要传回一个值,我会使用输出参数。

    示例存储过程,带有 OUTPUT 参数:

    CREATE PROCEDURE YourStoredProcedure 
    (
        @Param1    int
       ,@Param2    varchar(5)
       ,@Param3    datetime OUTPUT
    )
    AS
    IF ISNULL(@Param1,0)>5
    BEGIN
        SET @Param3=GETDATE()
    END
    ELSE
    BEGIN
        SET @Param3='1/1/2010'
    END
    RETURN 0
    GO
    

    使用 OUTPUT 参数调用存储过程:

    DECLARE @OutputParameter  datetime
           ,@ReturnValue      int
    
    EXEC @ReturnValue=YourStoredProcedure 1,null, @OutputParameter OUTPUT
    PRINT @ReturnValue
    PRINT CONVERT(char(23),@OutputParameter ,121)
    

    输出:

    0
    2010-01-01 00:00:00.000
    

    【讨论】:

    • 通过使用 OUTPUT 参数,您可以返回任何数据类型,存储过程中的 RETURN 值只能是整数。
    • 附带说明,声明为值的 OUTPUT 参数不需要传入。这意味着,如果您要更改现有的 SP,您可以安全地进行,而不会冒险破坏任何东西。例如,@Param3 datetime = '1900-01-01' 输出。
    【解决方案2】:

    如果您希望简单地返回一个整数,这将起作用:

    DECLARE @ResultForPos INT 
    EXEC @ResultForPos = storedprocedureName 'InputParameter'
    SELECT @ResultForPos
    

    【讨论】:

    • -1 这只会返回一个整数。 OP想要返回一个日期。 @KM 接受的答案。是正确的答案,因为它使用 OUTPUT 而不是 RETURN。
    • 实际上这行得通。关于如何获取返回的整数的示例,您可以对所有其他类型执行相同操作(没有检查表是否可能,但我认为是的。)我只是为 nvarchar(50) 尝试过。
    • @Mzn “你可以对所有其他类型做同样的事情”,当然不适用于UNIQUEIDENTIFIER
    • @James 为什么? uniqueidentifier 数据类型有什么不同?存储过程不能返回唯一标识符?
    • @Mzn UNIQUEIDENTIFIER 只是一个例子,RETURN 被设计为仅适用于整数值,请参阅docs。从 SP 获取其他数据的推荐方法是返回结果集或使用 OUTPUT
    【解决方案3】:
    declare @EventId int
    
    CREATE TABLE #EventId (EventId int)
    
    insert into #EventId exec rptInputEventId
    
    set @EventId = (select * from #EventId)
    
    drop table #EventId 
    

    【讨论】:

    • 实际上除了更改存储过程的签名之外,这里描述的唯一工作方式
    • 当底层 Sproc 也没有输出参数时,也将其用于日期。 (底层 sproc 内部有另一个来自动态 SQL 的 Exec)
    • @MichaelSander 完全正确,所有其他解决方案都没有正确回答了 OP 的问题。唯一的方法是保存结果的临时表。
    • 唯一可以在这里工作而不需要编辑 proc 的方法,在我的情况下我不能这样做。 +1
    • 您也可以使用表变量代替临时表。
    【解决方案4】:

    来自documentation(假设您使用SQL-Server):

    USE AdventureWorks;
    GO
    DECLARE @returnstatus nvarchar(15);
    SET @returnstatus = NULL;
    EXEC @returnstatus = dbo.ufnGetSalesOrderStatusText @Status = 2;
    PRINT @returnstatus;
    GO
    

    所以是的,它应该这样工作。

    【讨论】:

    • 在 OP 的示例中,他们想要返回日期,存储过程只能将整数值返回给调用过程或应用程序。
    • 这是不正确的。该文档正在谈论标量函数。 OP 正在询问带有结果集的存储过程。 @KM。请注意,即使源文档也将返回值分配给 nvarchar(15),而不是 int。
    【解决方案5】:

    我也有同样的问题。虽然这里有很好的答案,但我决定创建一个表值函数。使用表(或标量)值函数,您不必更改存储过程。我只是从表值函数中进行了选择。注意参数(MyParameter 是可选的)。

    CREATE FUNCTION [dbo].[MyDateFunction] 
    (@MyParameter varchar(max))
    RETURNS TABLE 
    AS
    RETURN 
    (
        --- Query your table or view or whatever and select the results.
        SELECT DateValue FROM MyTable WHERE ID = @MyParameter;
    )
    

    要分配给您的变量,您只需执行以下操作:

    Declare @MyDate datetime;
    SET @MyDate = (SELECT DateValue FROM MyDateFunction(@MyParameter));
    

    您还可以使用标量值函数:

    CREATE FUNCTION TestDateFunction()  
    RETURNS datetime  
    BEGIN  
        RETURN (SELECT GetDate());
    END
    

    那么你可以简单地做

    Declare @MyDate datetime;
    SET @MyDate = (Select dbo.TestDateFunction());
    SELECT @MyDate;
    

    【讨论】:

      【解决方案6】:

      这是动态查询的解决方案。

      例如,如果您有更多具有不同后缀的表:

      dbo.SOMETHINGTABLE_ONE, dbo.SOMETHINGTABLE_TWO
      

      代码:

      DECLARE @INDEX AS NVARCHAR(20)
      DECLARE @CheckVALUE AS NVARCHAR(max) = 'SELECT COUNT(SOMETHING) FROM 
      dbo.SOMETHINGTABLE_'+@INDEX+''
      DECLARE @tempTable Table (TempVALUE int)
      DECLARE @RESULTVAL INT
      
      INSERT INTO @tempTable
          EXEC sp_executesql @CheckVALUE
      
      SET @RESULTVAL = (SELECT * FROM @tempTable)
      
      DELETE @tempTable
      
      SELECT @RESULTVAL 
      

      【讨论】:

      • 这非常适合我的情况 - 谢谢
      【解决方案7】:

      您可以为此使用表变量

      代码:

      DECLARE @PreviousBusinessDay DATETIME
      DECLARE @Temp TABLE(BusinessDay DATETIME)
      INSERT INTO @Temp EXEC dbo.up_GetBusinessDay @Date, -1
      SET @PreviousBusinessDay = (SELECT * FROM @Temp)
      SELECT @PreviousBusinessDay
      

      https://www.sqlservertutorial.net/sql-server-user-defined-functions/sql-server-table-variables/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-01
        • 2010-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-04
        • 1970-01-01
        相关资源
        最近更新 更多