在SELECT语句中执行存储过程

4

举一个例子,我有一个select语句,它返回了1000行数据。我需要为每一行数据执行一个特定的存储过程。

你知道该如何实现吗?


你使用的是哪个服务器?SQL Server吗? - eKek0
5个回答

12

你可以像这样在SELECT语句中构建执行语句:

SELECT 'EXEC sp_whatever ' + parameter stuff
FROM   your_table

然后运行结果!或者,将结果粘贴到电子表格软件中,并使用字符串连接构建 EXEC 语句——只需创建一个公式并向下粘贴 1000 行即可。我个人更喜欢第一种方法。

为了澄清“参数”,以需要从 your_table 列中获取两个 int 参数的存储过程为例,您可以使用如下代码:

SELECT 'EXEC sp_whatever ' + CAST(field1 AS varchar) + ', ' + CAST(field2 AS varchar)
FROM    your_table

在这里不需要小心处理字符串字段-与任何SQL字符串连接一样,您会面临意外暴露自己的SQL注入攻击的风险。

我将你的“例如”解读为“这是一个一次性任务”。如果这是需要自动化的任务,则其他答案可能是正确的方法。


@Ben - 例如,如果你需要为每一行运行SP,并传递Field1和Field2列的值,假设两者都是整数,那么你可以这样写:'EXEC sp_whatever ' + CAST(Field1 AS varchar) + ', ' + CAST(Field2 AS varchar) FROM your_table。然后实际执行的命令将是EXEC sp_whatever 123, 456这种形式的。 - David M
这真的值得在4年后被打-1分吗? - David M
说实话,我没有检查日期。但是是的,对于我遇到的确切问题的答案不完整,甚至没有帮助。如果这不是一个踩票,我不知道什么才是。感谢更新。 - BenDundee
我昨天试图给你点赞,但只有在你编辑帖子后才能实现。其次,7个人发现你的答案有用意味着在互联网上有7个和我遇到相同问题的人比我更懂SQL,这并不特别令人惊讶。 - BenDundee
“..run the results!”?在创建了1-N语句后,如何运行结果而无需在Excel中进行连接? - ΩmegaMan
显示剩余2条评论

3
你可以这样做:
declare @execstatementsbatch nvarchar(max)

select @execstatementsbatch = ''

SELECT @execstatementsbatch = @execstatementsbatch   + 'EXEC UpdateQty ' + ItemCode +  ', '  + QtyBO +  '; ' 
FROM ITEMSPO 
INNER JOIN ..... 
<some conditions>

exec(@execstatementsbatch)

2
免责声明:我不确定我是否正确理解了你的问题。
假设你使用的是SQL Server 2005或更高版本,你可以创建一个表值用户定义函数,并在查询中使用OUTER APPLY操作符

是的,当然。这是我在2005年非常兴奋的许多事情之一。 - Mehrdad Afshari

1

大多数关系型数据库管理系统都可以从存储过程结果集中选择行。只需像使用普通表达式一样将存储过程放在FROM子句中即可。例如:

SELECT sp.ColumnInResultSet, t.BaseTableColumnName
FROM sp_whatever ( Args) sp INNER JOIN BaseTable t ON t.ID = sp.ID;

你知道哪些关系型数据库支持这个吗?我刚试了一下 SQL Server 2008,但没有成功。 - Alpha

0
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

        --PRINT @maincmd
        EXECUTE sp_executesql @maincmd
END

-----------------------------------------------
SELECT * FROM dbo.v_userwise_columns_value

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接