【问题标题】:How to use EXEC or sp_executeSQL without looping in this case?在这种情况下如何在不循环的情况下使用 EXEC 或 sp_executeSQL?
【发布时间】:2016-03-25 22:52:33
【问题描述】:

环境:SQL Server 2005/2008, 发布数据库

我已使用 information_schema 表将一组数据插入到表变量中,如下所示。

现在我想根据 dSQL 列中执行查询的结果更新标志列。我能够使用循环/光标进行更新,然后使用 sp_executeSQL 来 更新列,然后更新标志列。但是是否有另一种基于集合的方法来不循环遍历所有单独的行?

use pubs
go

declare @dsql Nvarchar(max)='', @tablename varchar(100), @colname varchar(100)
declare @t table (
 TABLE_NAME varchar(100),
 COLUMN_NAME varchar(100)
)

insert into @t
select distinct t.TABLE_NAME, c.COLUMN_NAME
from information_Schema.tables t
inner join
information_Schema.columns c
on t.TABLE_CATALOG = c.TABLE_CATALOG
where t.TABLE_SCHEMA = c.TABLE_SCHEMA
and t.TABLE_TYPE = 'BASE TABLE'
and c.DATA_TYPE = 'varchar'

select *, Dsql = 'select ' + COLUMN_NAME +  ' from ' + TABLE_NAME + ' WHERE '
+ COLUMN_NAME + ' = ''Menlo Park''', '' as Flag
FROM @t
GO   

我想创建一个函数并为每一行调用该函数以执行单独的查询语句,但为每条记录调用该函数可能会影响性能。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    它是你建议的循环或函数(无论如何这实际上是一个循环)。

    【讨论】:

      【解决方案2】:

      不可能,我之前也做过这样的脚本。

      declare @searchvalue varchar(100)
      
      set nocount off
      
      set @searchvalue = 'Hello world'
      
      
      create table #tt (table_name varchar(64), column_name varchar(64), count int)
      select * into #t from 
      (
      select 'select ''' + a.table_name + ''' ''table_name'',''' + a.column_name + ''' ''column_name'', count(*) count from [' + a.table_name +'] where [' +a.column_name+']='''+@searchvalue +'''' + ' group by ['+ a.column_name+']' sqlstring
      from INFORMATION_SCHEMA.COLUMNS a
      join 
      INFORMATION_SCHEMA.TABLES b
      on a.table_name = b.table_name
      and b.table_type = 'base table'
       where data_type = 'varchar'
      ) a
      
      --loop cursor
      Declare @sqlstring as nvarchar(500)
      Declare SqlCursor CURSOR FAST_FORWARD FOR
      SELECT sqlstring FROM #t
      OPEN SqlCursor
      FETCH NEXT FROM SqlCursor
      INTO @sqlstring
      WHILE @@FETCH_STATUS = 0
      BEGIN
      insert #tt
      exec(@sqlstring)
           FETCH NEXT FROM SqlCursor
           INTO @sqlstring
      END
      CLOSE SqlCursor
      DEALLOCATE SqlCursor
      select * from #tt
      drop table #tt
      drop table #t
      

      使用你想要的

      【讨论】:

      • 我已经有了光标解决方案,正在尝试一些不同的东西......但是谢谢!
      【解决方案3】:

      这是一个老问题,但我还是想添加一个不同的答案。

      尝试以下脚本(无游标,无循环(根据执行计划)):(在 MS SQL 2012 中测试)

      -- Setting up test data/code    
      SELECT  N'SELECT * FROM INFORMATION_SCHEMA.COLUMNS AS C' T
      INTO    #Code
      UNION ALL
      SELECT  N'SELECT * FROM INFORMATION_SCHEMA.TABLES AS T'
      
      -- Variable to hold the selected queries, seperated by CrLf. You can also add a "GO" or ";"    
      DECLARE @SQL NVARCHAR(MAX) = CHAR(13) + CHAR(10)
      
      -- Concatenate the selected queries together into the variable
      SELECT  @SQL = @SQL + CHAR(13) + CHAR(10) + C.T
      FROM    #Code AS C
      
      -- Execute   
      EXEC sys.sp_executesql @SQL
      
      -- Clean up    
      DROP TABLE #Code
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-19
        • 2012-01-31
        • 2021-10-30
        • 1970-01-01
        • 1970-01-01
        • 2014-07-06
        相关资源
        最近更新 更多