【问题标题】:How to execute a stored procedure inside a select query如何在选择查询中执行存储过程
【发布时间】:2013-01-08 12:50:50
【问题描述】:
SELECT col1,
       col2,
       col3,

EXEC GetAIntFromStoredProc(T.col1) AS col4
     FROM Tbl AS T
     WHERE (col2 = @parm) 

如何在 SQL Server 2008 中编写这个 SQL 查询?

【问题讨论】:

  • 你应该看看函数,你不能从选择查询中调用存储过程。
  • select col1, col2, col3, EXEC GetAIntFromStoredProc(t.col1) as col4 FROM tbl as t where (col2 = @parm) IS NOT select col1, col2 FROM EXEC MyStoredProc 'param1', 'param2 '。这不是重复的,尝试编辑但被拒绝,这篇文章的答案是正确的

标签: sql sql-server sql-server-2008 stored-procedures


【解决方案1】:

“不可能”。您可以使用此查询来执行此操作。 在这里初始化

declare @sql nvarchar(4000)=''

使用参数设置您的 sp 的值和执行命令

SET @sql += ' Exec spName @param'
EXECUTE sp_executesql @sql,  N'@param type', @param = @param

【讨论】:

  • 如果我错了请纠正我,但这看起来就像一个 SQL 注入正在等待发生
【解决方案2】:

“不可能”。 您可以使用函数而不是存储过程。

【讨论】:

    【解决方案3】:

    创建一个动态视图并从中获取结果......

    CREATE PROCEDURE dbo.usp_userwise_columns_value
    (
        @userid BIGINT
    )
    AS 
    BEGIN
            DECLARE @maincmd NVARCHAR(max);
            DECLARE @columnlist NVARCHAR(max);
            DECLARE @columnname VARCHAR(150);
            DECLARE @nickname VARCHAR(50);
    
            SET @maincmd = '';
            SET @columnname = '';
            SET @columnlist = '';
            SET @nickname = '';
    
            DECLARE CUR_COLUMNLIST CURSOR FAST_FORWARD
            FOR
                SELECT columnname , nickname
                FROM dbo.v_userwise_columns 
                WHERE userid = @userid
    
            OPEN CUR_COLUMNLIST
            IF @@ERROR <> 0
                BEGIN
                    ROLLBACK
                    RETURN
                END   
    
            FETCH NEXT FROM CUR_COLUMNLIST
            INTO @columnname, @nickname
    
            WHILE @@FETCH_STATUS = 0
                BEGIN
                    SET @columnlist = @columnlist + @columnname + ','
    
                    FETCH NEXT FROM CUR_COLUMNLIST
                    INTO @columnname, @nickname
                END
            CLOSE CUR_COLUMNLIST
            DEALLOCATE CUR_COLUMNLIST  
    
            IF NOT EXISTS (SELECT * FROM sys.views WHERE name = 'v_userwise_columns_value')
                BEGIN
                    SET @maincmd = 'CREATE VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), @userid) + ') as userid , ' 
                                + CHAR(39) + @nickname + CHAR(39) + ' as nickname, ' 
                                + @columnlist + ' compcode FROM dbo.SJOTran '
                END
            ELSE
                BEGIN
                    SET @maincmd = 'ALTER VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), @userid) + ') as userid , ' 
                                + CHAR(39) + @nickname + CHAR(39) + ' as nickname, ' 
                                + @columnlist + ' compcode FROM dbo.SJOTran '
                END
    
            EXECUTE sp_executesql @maincmd
    END
    
    -----------------------------------------------
    SELECT * FROM dbo.v_userwise_columns_value
    

    【讨论】:

    • 我认为使用光标不是这里的重点,并且扼杀了使用 Select 的全部意义
    • 在我的例子中,我需要光标,因为我想查看动态列并且我从其他用户映射表中获取它。
    【解决方案4】:

    您可以创建一个与您的 proc 输出匹配的临时表并插入其中。

    CREATE TABLE #Temp (
        Col1 INT
    )
    
    INSERT INTO #Temp
        EXEC MyProc
    

    【讨论】:

      【解决方案5】:

      函数很容易在选择循环中调用,但它们不允许您运行插入、更新、删除等操作。它们仅对查询操作有用。您需要一个存储过程来操作数据。

      因此,这个问题的真正答案是,您必须通过“游标”遍历 select 语句的结果,并从该循环中调用该过程。这是一个例子:

      DECLARE @myId int;
      DECLARE @myName nvarchar(60);
      DECLARE myCursor CURSOR FORWARD_ONLY FOR
          SELECT Id, Name FROM SomeTable;
      OPEN myCursor;
      FETCH NEXT FROM myCursor INTO @myId, @myName;
      WHILE @@FETCH_STATUS = 0 BEGIN
          EXECUTE dbo.myCustomProcedure @myId, @myName;
          FETCH NEXT FROM myCursor INTO @myId, @myName;
      END;
      CLOSE myCursor;
      DEALLOCATE myCursor;
      

      请注意,@@FETCH_STATUS 是为您更新的标准变量。此处的其余对象名称是自定义的。

      【讨论】:

        【解决方案6】:

        感谢@twoleggedhorse。

        这里是解决方案。

        1. 首先我们创建了一个函数

          CREATE FUNCTION GetAIntFromStoredProc(@parm Nvarchar(50)) RETURNS INTEGER
          
          AS
          BEGIN
             DECLARE @id INTEGER
          
             set @id= (select TOP(1) id From tbl where col=@parm)
          
             RETURN @id
          END
          
        2. 然后我们进行选择查询

          Select col1, col2, col3,
          GetAIntFromStoredProc(T.col1) As col4
          From Tbl as T
          Where col2=@parm
          

        【讨论】:

        • 没错。正确答案应该是“不可能”。
        • 这不是针对程序提出的字面问题的答案。这是一个具有巨大局限性的替代解决方案。查看我的实际答案。
        • 如何解决您刚刚将存储过程转换为函数的问题:/
        • 如果存储过程有动态查询要执行怎么办?它不适用于函数。
        【解决方案7】:

        只要您不在存储过程中执行任何 INSERT 或 UPDATE 语句,您可能希望将其设为函数。

        存储过程用于由外部程序执行,或按时间间隔执行。

        这里的答案会比我解释得更好:

        Function vs. Stored Procedure in SQL Server

        【讨论】:

        • 存储过程可以用于“由外部程序执行,或按时间间隔执行”,但它们绝不限于此,或仅用于这些目的。脚本始终编写为在独立的按需上下文中运行以进行数据操作。
        猜你喜欢
        • 2013-03-12
        • 2015-02-15
        • 1970-01-01
        • 1970-01-01
        • 2020-04-04
        • 2012-12-26
        • 2013-10-11
        • 2018-03-09
        • 2019-04-08
        相关资源
        最近更新 更多