如何使用列值查找清单表

How to find List Tables using columns value

我在数据库中有 500 多个表。所有表格都有几列。其中有些表有'CMDFLAG'列,列的值可能有'C'或'D'或'M'。

我的要求是找到 CMDFLAG 为“C”或“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”或“D”或 'M'.

的表列表

我已经回答了几个问题,但无法满足我的要求。此外,我想使用简单的查询而不是过程。

您可以按如下方式进行。

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;

这样的事情怎么样:

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

试试这个。我必须使用动态查询和临时 tables,因为 EXEC 不适用于常见的 table 表达式。

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