найти имя столбца или имя таблицы определенного значения

Я хочу найти определенное значение в моей базе данных, и я не знаю, где именно оно находится. Существует ли какой-либо запрос, возвращающий имя столбца или имя таблицы определенного значения на сервере SQL? Предположим, что у меня есть значение столбца, например 123, но я не знаю, к какой таблице принадлежит 123, и я ничего не знаю об имени его столбца. Могу ли я написать запрос, чтобы найти имена таблиц, в которых есть это значение? Мне нужен запрос, а не процедура!!!


person Gohar    schedule 08.11.2016    source источник
comment
Если это база данных, которую вы разработали, скорее всего, это признак неработающей модели данных. Значения одного и того же типа, сравнимые или вычисляемые, должны храниться в одном столбце одной таблицы. Если они хранятся в нескольких столбцах/таблицах, вполне вероятно, что значения, которые должны быть данными, вместо этого были встроены в модель в виде метаданных, таких как имена столбцов или таблиц.   -  person Damien_The_Unbeliever    schedule 08.11.2016


Ответы (1)


Это может сделать это для вас. Обратите внимание, что если у вас много таблиц/столбцов, это может занять некоторое время. Если вы не ищете в столбцах (N)VARCHAR, вы можете добавить эти типы в предложение c.DATA_TYPE NOT IN(.... Или любой другой тип, который вы не ищете (например, FLOAT или DECIMAL).

SET NOCOUNT ON;
DECLARE @value NVARCHAR(MAX)='123';
CREATE TABLE #found(table_name SYSNAME,column_name SYSNAME);
DECLARE @sql NVARCHAR(MAX)=(
    SELECT
        'INSERT INTO #found(table_name,column_name) ' +
        'SELECT TOP 1 '+
            'table_name='''+REPLACE(t.TABLE_NAME,'''','''''')+''','+
            'column_name='''+REPLACE(c.COLUMN_NAME,'''','''''')+''' '+
        'FROM '+
            QUOTENAME(t.TABLE_SCHEMA)+'.'+QUOTENAME(t.TABLE_NAME)+' '+
        'WHERE '+
            QUOTENAME(c.COLUMN_NAME)+'='''+REPLACE(@value,'''','''''')+''';'
    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.DATA_TYPE NOT IN('BIT','NTEXT','TEXT','IMAGE','BINARY','VARBINARY','DATETIME','DATE','DATETIME2','TIME','SMALLDATETIME','DATETIMEOFFSET')
    FOR XML
        PATH('')
);

EXECUTE (@sql);
SELECT * FROM #found ORDER BY table_name,column_name;
DROP TABLE #found;
person TT.    schedule 08.11.2016
comment
Примечание. Может быть лучше ограничить типы, которые вы ищете, написав c.DATA_TYPE IN(..., а не c.DATA_TYPE NOT IN(..., если вы знаете, какие типы данных вы ищете. - person TT.; 08.11.2016