我有一个包含大约 +100 个表的数据库,比如一半的表有 A 列和 B 列。
我的问题是,我可以查询所有具有特定值的列的表,例如
从数据库中选择 *
在哪里
EACHTABLE HAS COLUMN A = 21 //仅当表有列和值时
和
B栏= 13
我不确定我会做多准确,谷歌也没有任何内容
我有一个包含大约 +100 个表的数据库,比如一半的表有 A 列和 B 列。
我的问题是,我可以查询所有具有特定值的列的表,例如
从数据库中选择 *
在哪里
EACHTABLE HAS COLUMN A = 21 //仅当表有列和值时
和
B栏= 13
我不确定我会做多准确,谷歌也没有任何内容
sp_MSforeachtable
如果您喜欢肆无忌惮地生活,您可以使用未记录的 MS 存储过程:
create table T1 (
ColumnA int not null,
ColumnB int not null
)
go
create table T2 (
ColumnA int not null,
Column2 int not null
)
go
create table T3 (
Column1 int not null,
ColumnB int not null
)
go
create table T4 (
ColumnA int not null,
ColumnB int not null
)
go
insert into T1 values (1,2);
insert into T2 values (3,4);
insert into T3 values (5,6);
insert into T4 values (7,8);
go
create table #Results (TableName sysname,ColumnA int,ColumnB int)
exec sp_MSforeachtable 'insert into #Results select ''?'',ColumnA,ColumnB from ?',
@whereand = ' and syso.object_id in (select object_id from sys.columns where name=''ColumnA'') and syso.object_id in (select object_id from sys.columns where name=''ColumnB'')'
select * from #Results
drop table #Results
结果:
TableName ColumnA ColumnB
------------------------------------- ----------- -----------
[dbo].[T1] 1 2
[dbo].[T4] 7 8
默认情况下,sp_MSforeachtable
顾名思义,将为数据库中的每个表执行相同的任务。但是,此过程的一个可选参数称为@Whereand
,可用于修改WHERE
枚举数据库中的表的内部查询的子句。知道这个内部查询已经为某些系统视图建立了两个别名会有所帮助。o
是sysobjects
(遗留系统视图)的别名。syso
是sys.all_objects
(更现代的系统视图)的别名。
一旦sp_MSforeachtable
决定了要针对哪些表运行,它将执行作为其第一个参数提供给它的查询。但是,它将替换?
为架构和表名(?
是默认替换字符。可以根据需要更改)
在这种情况下,我选择创建一个临时表,然后让每个选定的表将其结果存储到该临时表中,并在sp_MSforeachtable
运行完成后,将组合结果选择出来,无需进一步处理。
有一个类似的(同样未记录的)过程sp_MSforeachdb
将访问服务器上的每个用户数据库。这些甚至可以组合起来(尽管有时您必须小心将'
引号字符加倍)。但是,没有等效的sp_MSforeachcolumn
.
试试这个:
select t.name from sys.objects t inner join sys.columns c
on t.name=OBJECT_NAME(c.object_id)
where t.type='U'
and c.name in('col1','col2')
group by t.name
having COUNT(*) = 2
order by 1
然后,您只需遍历所有表并微调这些列的值。
像
Declare @out TABLE(tblname varchar(100))
if exists(select * from tbl1 where col1='21' and col2='22')
BEGIN
INSERT INTO @out
select tbl1
END
您可以尝试使用动态查询。
select 'select * from '+table_name+ ' where'+column_name+'=21'
from information_schema.columns where column_name = 'A'
我建议使用两个步骤:首先,找出数据库中包含这两列的所有表,并将其用于时间派生表。因为我不是 SQL-Server 2008 方面的专家,所以我建议您查看白皮书。
表达式可能如下所示:
SELECT tablename
FROM information_schema.tables sdbt
WHERE "column a" IN
(SELECT columns
FROM information_schema.columns col
WHERE col.tablename = sdbt.tablename)
其次,使用表达式根据您的要求值过滤结果。
此命令应该一次性完成,仅适用于 A 列,相应地修改以包含您需要的任何其他列:
exec sp_MSforeachtable
@command1=N'SELECT * FROM ? WHERE A = 21',
@whereand=' and o.name IN (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = ''A'') '