【问题标题】:Execution of Stored Procedure for every row of table using string variable使用字符串变量对表的每一行执行存储过程
【发布时间】:2018-05-25 09:43:38
【问题描述】:

我想在不使用游标或循环的情况下为表的每一行执行存储过程。 假设我的表 dbo.User 包含以下用户的名称:

create table dbo.test_User  ( 
 Name varchar(50) )

insert into dbo.test_User  
   values  ('Deepanshu'),('IronMan'),('DoctorStrange')

我创建了一个只显示用户名的存储过程(虽然我真正的存储过程要做很多事情)

create procedure dbo.usp_TestSP ( @name varchar(50) )
as
BEGIN
    select @name
END

现在我希望为所有名称运行存储过程,例如:

EXEC dbo.usp_TestSP 'Deepanshu';
EXEC dbo.usp_TestSP 'IronMan';
EXEC dbo.usp_TestSP 'DoctorStrange';

我创建了一个字符串变量@Query,它将存储我要执行的 t-sql 查询

DECLARE @Query varchar(200);  
select @Query=STUFF(  
                    (select 'dbo.usp_TestSP '''+Name+''';' 
                     from dbo.test_user  
                     FOR XML PATH('')
                    ),1,0,''
                 )  
EXEC @Query

当我尝试执行此@Query 时,它给了我一个错误提示:

在 sys.servers 中找不到服务器“dbo”。验证是否指定了正确的服务器名称。如有必要,执行存储过程 sp_addlinkedserver 将服务器添加到 sys.servers。

如何使用字符串变量@Query 为所有名称执行存储过程?

【问题讨论】:

标签: sql sql-server tsql stored-procedures


【解决方案1】:

您可以使用CURSOR 模拟带有存储过程调用的FOR-EACH

DECLARE db_cursor CURSOR LOCAL FAST_FORWARD FOR 
SELECT *FROM  dbo.tesT_User;

DECLARE @name NVARCHAR(50);

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @name;

WHILE @@FETCH_STATUS = 0  
BEGIN  
      EXEC dbo.usp_TestSP @name = @name;

      FETCH NEXT FROM db_cursor INTO @name;
END 

CLOSE db_cursor;
DEALLOCATE db_cursor;

DBFiddle Demo


警告:

如果它是简单的函数,那么CROSS/OUTER APPLY 是一种方法。

SELECT *
FROM dbo.Test_User tu
OUTER APPLY (SELECT dbo.usp_TestSP(tu.name)) s(a);

DBFiddle Demo2


编辑

我想在没有光标或循环的情况下执行此操作,使用与上面显示的相同的逻辑

DECLARE @x NVARCHAR(MAX) = 
   (SELECT string_agg(FORMATMESSAGE('EXEC dbo.usp_TestSP @name=''%s'';', name)
   ,CHAR(13)) AS r FROM dbo.test_User);
PRINT @x;
EXEC(@x);

DBFiddle Demo3


最后是你的代码:

DECLARE @Query varchar(MAX);  
select @Query=STUFF((SELECT 'EXEC dbo.usp_TestSP @name=' +QUOTENAME(Name,'''') 
       + ';' from dbo.test_user
FOR XML PATH('')),1,0,'');
EXEC(@Query);

DBFiddle Demo4

我做了什么:

  • 使用分号 (;) 是非常好的做法
  • 将数据类型更改为VARCHAR(MAX)
  • 在 SQL 中添加了EXEC
  • ()包裹@Query

【讨论】:

  • 要处理嵌入的引号,我建议(select 'EXEC dbo.usp_TestSP ' +QUOTENAME(Name,'''') + ';' from dbo.test_user
猜你喜欢
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
  • 2016-01-21
  • 2023-03-25
  • 1970-01-01
  • 2011-01-07
相关资源
最近更新 更多