如果我不知道该如何查找具有列值的表

时间:2019-01-10 09:25:50

标签: sql sql-server tsql

我们有一个由第三方创建的用于工作的应用程序。因此,我们可以访问UI,而不能访问后端代码。在此应用程序上有一个下拉列表。我确实可以访问运行该应用程序的MSSQL DB。

我需要知道该下拉列表从何处获取其信息,但我不知道它使用的是哪个表(因为我无法直接检查代码)。

是否可以编写查询以在整个数据库中搜索具有包含特定值的列的表?

下拉列表值为:

  • 网站APP
  • BOT应用
  • 沃尔金
  • BotLead

5 个答案:

答案 0 :(得分:3)

您可以使用SQL Server ProfilerExtended Events session来捕获针对数据库的已执行语句。最简单的方法是使用SSMS XEvent Profiler功能(在Management Studio版本17.3中引入)。本质上,您将开始捕获执行的语句,打开应用程序以使其加载列表,停止跟踪并查看捕获的查询以确定数据源。

答案 1 :(得分:1)

您可以根据INFORMATION_SCHEMA.COLUMNS中的信息尝试生成并执行动态SQL语句:

DECLARE @stm nvarchar(max)
SET @stm = N''

SELECT @stm = @stm +
    N'SELECT ' +
    N'''' + TABLE_NAME + N''' AS TableName, ' +
    N'''' + COLUMN_NAME + N''' AS ColumnName, ' +
    QUOTENAME(COLUMN_NAME) + 
    N' FROM ' + QUOTENAME(TABLE_NAME) +
    N' WHERE ' + QUOTENAME(COLUMN_NAME) + N' IN (''WebsiteAPP'', ''BOT App'', ''Walkin'', ''BotLead''); '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE 
    DATA_TYPE = ('varchar') OR 
    DATA_TYPE = ('nvarchar');

PRINT @stm
EXEC sp_executesql @stm

或者只获取表中的所有SQL语句并根据需要执行它们:

SELECT
    N'SELECT ' +
    N'''' + TABLE_NAME + N''' AS TableName, ' +
    N'''' + COLUMN_NAME + N''' AS ColumnName, ' +
    QUOTENAME(COLUMN_NAME) + 
    N' FROM ' + QUOTENAME(TABLE_NAME) +
    N' WHERE ' + QUOTENAME(COLUMN_NAME) + N' IN (''WebsiteAPP'', ''BOT App'', ''Walkin'', ''BotLead''); '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE 
    DATA_TYPE = ('varchar') OR 
    DATA_TYPE = ('nvarchar');

答案 2 :(得分:0)

您可以查询ADC->CCRsys.tables来找到包含文本信息的table.column列表,然后从中生成许多sql查询 sys.columns

答案 3 :(得分:0)

USE AdventureWorks;
GO

SET NOCOUNT ON;

DECLARE @T TABLE (ColumnName SYSNAME, TableName SYSNAME);

DECLARE
    @SearchString VARCHAR(255) = 'Simon',
    @SQL NVARCHAR(MAX);

DECLARE CUR CURSOR LOCAL FAST_FORWARD FOR
SELECT
    'SELECT ' + 
        QUOTENAME(c.name) + ', ''' + 
        OBJECT_SCHEMA_NAME(c.object_id) + '.' + OBJECT_NAME(c.object_id) + 
    ''' FROM ' + QUOTENAME(OBJECT_SCHEMA_NAME(c.object_id)) + '.' + QUOTENAME(OBJECT_NAME(c.object_id)) + 
    ' WHERE ' + QUOTENAME(c.name) + ' = ''' + @SearchString + ''';'
FROM
    sys.columns c
INNER JOIN
    sys.types t
        ON c.user_type_id = t.user_type_id
WHERE
    c.collation_name IS NOT NULL
    AND t.name NOT IN ('text','ntext')
    AND OBJECTPROPERTY(c.object_id,'IsSystemTable') = 0
    AND OBJECTPROPERTY(c.object_id,'IsMSShipped') = 0
    AND OBJECTPROPERTY(c.object_id,'IsTable') = 1;

OPEN CUR;
FETCH CUR INTO @SQL;
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @SQL;

    INSERT INTO @T
    EXEC sp_executesql @SQL;

    FETCH CUR INTO @SQL;
END;
CLOSE CUR;
DEALLOCATE CUR;

SELECT DISTINCT
    *
FROM
    @T;

答案 4 :(得分:0)

您可以通过以下查询来实现所需的功能,只需将MyDatabase替换为数据库名称(代码中必要的注释)即可:

-- define cursor to loop through all columns
declare crs cursor for
select object_name(object_id), name from MyDatabase.sys.columns
where collation_name is not null --here we add this constraint to check only varchar columns
declare @tableName varchar(1000), @columnName varchar(1000), @sql varchar(1000);

open crs
fetch next from crs into @tableName, @columnName
while @@FETCH_STATUS = 0
begin
    -- craete dynamic sql, which will check if all values exist in that column, if so, print table name
    set @sql = 'if exists(select * from MyDatabase..' + @tableName + ' where ' + @columnName + ' = ''Value1'') ' +
    -- to add more values, just modify this dynamic sql (add another exist(...))
        'and exists(select * from MyDatabase..' + @tableName + ' where ' + @columnName + ' = ''Value2'') '
        'and exists(select * from MyDatabase..' + @tableName + ' where ' + @columnName + ' = ''Value3'') print ''' + @tableName + ''';'
    exec (@sql)
    fetch next from crs into @tableName, @columnName
end
close crs
deallocate crs

注意:它将产生一些错误,但其中将打印表格名称,只需查找即可:)