SQL Server для проверки всех столбцов в представлениях базы данных на предмет конкретного строкового значения - PullRequest
0 голосов
/ 17 января 2019

У моего работодателя есть стороннее приложение, которое имеет очень сложный набор косвенно именованных представлений. Я пытаюсь найти представления, содержащие конкретные данные, которые вводятся в пользовательский интерфейс приложения.

У меня есть SQL для построения CTE со всеми именами представлений и именами столбцов ...

Что я не могу понять, так это как проверить каждый столбец (который может содержать строковое значение) в каждом представлении для определенного строкового значения.

Вот мой старт, который не работает, но проиллюстрирует, что я пытаюсь сделать. Обратите внимание, что также отсутствует ограничение на столбцы для проверки на основе того, что может содержать строковое значение.

Другая очевидная проблема с приведенным ниже состоит в том, что я хочу оценить значение столбца, а НЕ имя столбца для значения.

WITH ViewColumn_CTE (ViewName, ColumnName) AS
(
    SELECT TOP 100
        V.Name as ViewName, 
        C.Name as ColumnName
    FROM
        sys.views V 
    JOIN
        SysColumns C ON V.Object_ID = C.ID
)
SELECT TOP 1
    ViewName,
    ColumnName
FROM
    ViewColumn_CTE
WHERE
    ColumnName = 'Cash Equivalents'

1 Ответ

0 голосов
/ 18 января 2019

У меня такой сценарий летает здесь. Вы можете использовать его для начала.

Он получает список интересных столбцов из каталога итераций по ним и запрашивает их, используя динамический SQL.

DECLARE @searched_value nvarchar(MAX) = 'a'; -- set to the value you search for

SET NOCOUNT ON;

DECLARE @schema_name sysname;
DECLARE @table_name sysname;
DECLARE @column_name sysname;
DECLARE @sql nvarchar(MAX);
DECLARE @result TABLE ([schema_name] sysname,
                       [table_name] sysname,
                       [column_name] sysname,
                       [value] nvarchar(MAX));

DECLARE cursor_all_columns CURSOR
                           LOCAL
                           FAST_FORWARD
FOR
SELECT s.name,
       o.name,
       c.name
       FROM sys.schemas s
            INNER JOIN sys.all_objects o
                       ON o.schema_id = s.schema_id
            INNER JOIN sys.all_columns c
                       ON c.object_id = o.object_id
            INNER JOIN sys.types y
                       ON y.user_type_id = c.user_type_id
       WHERE o.type = 'U' -- set to 'V' for views
             AND lower(y.name) IN ('char',
                                   'nchar',
                                   'varchar',
                                   'nvarchar'); -- include more types if needed

OPEN cursor_all_columns;
FETCH NEXT FROM cursor_all_columns
           INTO @schema_name,
                @table_name,
                @column_name;
WHILE @@fetch_status = 0
BEGIN
  SET @sql =   N'SELECT ''' + quotename(@schema_name) + N''',' + nchar(13) + nchar(10)
             + N'       ''' + quotename(@table_name) + N''',' + nchar(13) + nchar(10)
             + N'       ''' + quotename(@column_name) + N''',' + nchar(13) + nchar(10)
             + N'       ' + quotename(@column_name) + N'' + nchar(13) + nchar(10)
             + N'       FROM ' + quotename(@schema_name) + N'.' + quotename(@table_name) + N'' + nchar(13) + nchar(10)
             + N'       WHERE lower(' + quotename(@column_name) + N') LIKE N''%' + lower(replace(replace(replace(@searched_value, '%', '!%'), '[', '!['), ']', '!]')) + N'%'' ESCAPE ''!'';' + nchar(13) + nchar(10);

  INSERT INTO @result
              EXEC sp_executesql @sql;

  FETCH NEXT FROM cursor_all_columns
             INTO @schema_name,
                  @table_name,
                  @column_name;
END;
CLOSE cursor_all_columns;
DEALLOCATE cursor_all_columns;

SELECT [schema_name],
       [table_name],
       [column_name],
       [value]
       FROM @result;

Is предназначен для таблиц, но он также должен работать для представлений, если вы измените тип объекта с 'U' на 'V'. (Хотя в любом случае таблицы могут быть более интересными.) Никаких гарантий.

Установите искомое значение в начале.

Поиск любого столбца типа (n)(var)char, если он содержит искомое значение, без учета регистра. Если вы хотите, чтобы любые пользовательские типы были получены из строковых типов, вы должны соответствующим образом адаптировать их.

Выходными данными являются схема, имя таблицы (или представления), имя столбца и соответствующее значение (столбец может быть указан несколько раз, если в этом столбце искомое значение содержится в нескольких строках).

(Отказ от ответственности: может быть место для улучшений или ошибок.)

...