环境: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
我有一个想法是创建一个函数并为每一行调用函数来执行单独的查询语句,但为每条记录调用函数可能会影响性能。
答案 0 :(得分:1)
这是你建议的循环或函数(无论如何它都是一个循环)。
答案 1 :(得分:0)
不可能,我之前制作了一个类似的剧本。
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
使用你想要的东西
答案 2 :(得分:0)
这是一个老问题,但我想添加一个不同的答案。
尝试以下脚本(没有游标,没有循环(根据执行计划)):(在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