我在数据库中有500多个表。所有表都有几列。其中有些表有'CMDFLAG'列,列的值可能有'C'or'D'或'M'。
我的要求是找到CMDFLAG为'C'or'D'或'M'的表格列表。
Table Name Column Name Value
---------- ----------- -----
Table_A CMDFLAG C
Table_A CMDFLAG D
Table_A CMDFLAG M
Table_B CMDFLAG C
Table_B CMDFLAG D
Table_C CMDFLAG M
等......
我可以使用INFORMATION_SCHEMA.COLUMNS查找具有CMDFLAG列的表列表。但是我想查找CMDFLAG列具有值'C'or'D'或'M'的表格列表。
我已经完成了几个问题,但无法满足我的要求。而且我想使用简单的查询而不是程序。
答案 0 :(得分:1)
您可以按照以下方式执行此操作。
SET NOCOUNT ON;
DECLARE @colname SYSNAME='CMDFLAG';
CREATE TABLE #tablenames(tablename SYSNAME,colname SYSNAME,colval NVARCHAR(128));
DECLARE @dsql NVARCHAR(MAX)= (
SELECT
N'INSERT INTO #tablenames(tablename,colname,colval)'+
N'SELECT DISTINCT ' +
'tablename='''+REPLACE(t.TABLE_NAME,N'''',N'''''')+N''','+
'colname='''+REPLACE(@colname,N'''',N'''''')+N''','+
'colval='+QUOTENAME(@colname)+N' '+
N'FROM '+QUOTENAME(t.TABLE_SCHEMA)+N'.'+QUOTENAME(t.TABLE_NAME)+N' '+
N'WHERE '+QUOTENAME(@colname)+N' IN (''C'',''D'',''M'');'
FROM
INFORMATION_SCHEMA.TABLES AS t
INNER JOIN INFORMATION_SCHEMA.COLUMNS AS c ON
c.TABLE_SCHEMA=t.TABLE_SCHEMA AND
c.TABLE_NAME=t.TABLE_NAME
WHERE
t.TABLE_TYPE='BASE TABLE' AND
c.COLUMN_NAME=@colname
FOR
XML PATH('')
);
EXECUTE sp_executesql @dsql;
SELECT * FROM #tablenames ORDER BY tablename;
DROP TABLE #tablenames;
答案 1 :(得分:1)
这样的事情怎么样:
DECLARE @ColumnName sysname = 'CMDFLAG', @Sql NVARCHAR(MAX)
IF OBJECT_ID(N'TempDB.dbo.#Results', N'U') IS NULL
CREATE TABLE #Results(TableName SYSNAME, RowCounts INT)
ELSE
TRUNCATE TABLE #Results
SELECT
@Sql = 'INSERT INTO #Results '
+ STUFF((
SELECT
'UNION ALL SELECT Table_Name = '
+ QUOTENAME(C.TABLE_SCHEMA + '.' + C.TABLE_NAME, '''')
+ ', NumRows = COUNT(*)'
+ ' FROM '
+ QUOTENAME(C.TABLE_SCHEMA) + '.'
+ QUOTENAME(C.TABLE_NAME )
+ ' WHERE ' + QUOTENAME(C.COLUMN_NAME) + ' IN(''C'', ''D'', ''M'') '
+ ' GROUP BY ' + QUOTENAME(C.COLUMN_NAME)
+ ' HAVING COUNT(*) > 0 '
FROM
INFORMATION_SCHEMA.COLUMNS C
CROSS APPLY
(
SELECT
T.TABLE_SCHEMA, T.TABLE_NAME
FROM
INFORMATION_SCHEMA.TABLES T
WHERE
T.TABLE_TYPE = 'BASE TABLE'
AND T.TABLE_SCHEMA = C.TABLE_SCHEMA
AND T.TABLE_NAME = C.TABLE_NAME
) T
WHERE
C.COLUMN_NAME = @ColumnName
FOR XML PATH(''), type).value('.', 'nvarchar(max)'), 1, 10, '')
EXEC(@Sql)
SELECT * FROM #Results
好的,这应该做你想要的:
DECLARE @ColumnName sysname = 'CMDFLAG', @Sql NVARCHAR(MAX)
IF OBJECT_ID(N'TempDB.dbo.#Results', N'U') IS NULL
CREATE TABLE #Results(TableName SYSNAME, ColumnName sysname, Value NVARCHAR(25))
ELSE
TRUNCATE TABLE #Results
SELECT
@Sql = 'INSERT INTO #Results '
+ STUFF((
SELECT
'UNION ALL SELECT DISTINCT Table_Name = '
+ QUOTENAME(C.TABLE_SCHEMA + '.' + C.TABLE_NAME, '''')
+ ', ' + QUOTENAME(C.COLUMN_NAME, '''')
+ ', ' + QUOTENAME(C.COLUMN_NAME)
+ ' FROM '
+ C.TABLE_SCHEMA + '.'
+ C.TABLE_NAME
+ ' WHERE ' + QUOTENAME(C.COLUMN_NAME) + ' IN(''C'', ''D'', ''M'') '
FROM
INFORMATION_SCHEMA.COLUMNS C
CROSS APPLY
(
SELECT
T.TABLE_SCHEMA, T.TABLE_NAME
FROM
INFORMATION_SCHEMA.TABLES T
WHERE
T.TABLE_TYPE = 'BASE TABLE'
AND T.TABLE_SCHEMA = C.TABLE_SCHEMA
AND T.TABLE_NAME = C.TABLE_NAME
) T
WHERE
C.COLUMN_NAME = @ColumnName
FOR XML PATH(''), type).value('.', 'nvarchar(max)'), 1, 10, '')
EXEC(@Sql)
SELECT * FROM #Results
答案 2 :(得分:1)
试试这个。我必须使用动态查询和临时表,因为EXEC
不适用于公用表表达式。
CREATE TABLE #t1
(
tableName varchar(30),
RN INT
)
CREATE TABLE #t2
(
tableName varchar(30),
columnName varchar(30),
value char(1)
)
INSERT INTO #t1
SELECT C.TABLE_NAME, ROW_NUMBER() OVER(ORDER BY TABLE_NAME) AS RN
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.COLUMN_NAME = 'CMDFLAG'
DECLARE @COUNT AS INT = (SELECT COUNT(1) FROM #t1)
DECLARE @Iterator AS INT = 1
DECLARE @tableName AS VARCHAR(30)
DECLARE @script AS VARCHAR(200)
WHILE @Iterator <= @COUNT
BEGIN
SELECT @tableName = (SELECT tableName FROM #t1 WHERE RN = @Iterator)
SELECT @script = 'SELECT '''+@tableName+''', ''CMDFLAG'', CMDFLAG FROM '+@tableName+' GROUP BY CMDFLAG'
INSERT INTO #t2
EXEC(@script)
SELECT @Iterator = @Iterator + 1
END
SELECT * FROM #t2
DROP TABLE #t1
DROP TABLE #t2