如何使用列值查找列表表

时间:2016-11-06 05:24:36

标签: sql sql-server tsql sql-server-2012

我在数据库中有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'的表格列表。

我已经完成了几个问题,但无法满足我的要求。而且我想使用简单的查询而不是程序。

3 个答案:

答案 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