1

我有一个包含大约 +100 个表的数据库,比如一半的表有 A 列和 B 列。

我的问题是,我可以查询所有具有特定值的列的表,例如

从数据库中选择 *

在哪里

EACHTABLE HAS COLUMN A = 21 //仅当表有列和值时

B栏= 13

我不确定我会做多准确,谷歌也没有任何内容

4

5 回答 5

2

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枚举数据库中的表的内部查询的子句。知道这个内部查询已经为某些系统视图建立了两个别名会有所帮助。osysobjects(遗留系统视图)的别名。sysosys.all_objects(更现代的系统视图)的别名。

一旦sp_MSforeachtable决定了要针对哪些表运行,它将执行作为其第一个参数提供给它的查询。但是,它将替换?为架构和表名(?是默认替换字符。可以根据需要更改)

在这种情况下,我选择创建一个临时表,然后让每个选定的表将其结果存储到该临时表中,并在sp_MSforeachtable运行完成后,将组合结果选择出来,无需进一步处理。

有一个类似的(同样未记录的)过程sp_MSforeachdb将访问服务器上的每个用户数据库。这些甚至可以组合起来(尽管有时您必须小心将'引号字符加倍)。但是,没有等效的sp_MSforeachcolumn.

于 2012-08-15T08:51:10.820 回答
1

试试这个:

 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
于 2012-08-15T08:55:17.950 回答
0

您可以尝试使用动态查询。

select 'select * from '+table_name+ ' where'+column_name+'=21'
from information_schema.columns where column_name = 'A'
于 2012-08-15T08:38:40.657 回答
0

我建议使用两个步骤:首先,找出数据库中包含这两列的所有表,并将其用于时间派生表。因为我不是 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)

其次,使用表达式根据您的要求值过滤结果。

于 2012-08-15T08:43:03.130 回答
0

此命令应该一次性完成,仅适用于 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'') '
于 2012-08-15T08:48:16.043 回答