Найти все хранимые процедуры, которые ссылаются на определенный столбец в некоторой таблице

У меня есть значение в таблице, которое было неожиданно изменено. Рассматриваемый столбец CreatedDate: он устанавливается при создании моего элемента, но изменяется хранимой процедурой.

Могу ли я написать какой-нибудь оператор SELECT, чтобы получить все имена процедур, которые ссылаются на этот столбец, из моей таблицы?


person Pomster    schedule 23.10.2013    source источник
comment
Взгляните на таблицу sys.all_sql_modules. В частности, столбец под названием definition   -  person gvee    schedule 23.10.2013
comment
Возможный дубликат: stackoverflow.com/questions/686247/   -  person StuartLC    schedule 23.10.2013
comment
Я нашел stackoverflow.com/a/8757152/9695286, этот ответ более точен   -  person Karan    schedule 23.04.2021


Ответы (8)


Один из вариантов - создать файл сценария.

Щелкните правой кнопкой мыши базу данных -> Задачи -> Создать сценарии.

Затем вы можете выбрать все хранимые процедуры и сгенерировать сценарий со всеми sps. Так что вы можете найти ссылку оттуда.

Or

-- Search in All Objects
SELECT OBJECT_NAME(OBJECT_ID),
definition
FROM sys.sql_modules
WHERE definition LIKE '%' + 'CreatedDate' + '%'
GO

-- Search in Stored Procedure Only
SELECT DISTINCT OBJECT_NAME(OBJECT_ID),
object_definition(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'CreatedDate' + '%'
GO

Источник SQL SERVER - Найти столбец, используемый в хранимой процедуре - Поиск хранимой процедуры по имени столбца

person huMpty duMpty    schedule 23.10.2013
comment
Будет ли это просто найти объекты / процедуры с определенным параметром, который соответствует предложению WHERE, или это также найдет ссылки на MyTable.SomeColumn в самих объектах? - person sab669; 15.11.2016
comment
Идеально! У меня отлично работает. Спасибо - person Eduardo; 21.05.2019

Если вы хотите получить хранимые процедуры, используя только определенный столбец, вы можете использовать этот запрос:

SELECT DISTINCT Name
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%CreatedDate%';

Если вы хотите получить хранимые процедуры с использованием определенного столбца таблицы, вы можете использовать следующий запрос:

SELECT DISTINCT Name 
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%tbl_name%'
AND OBJECT_DEFINITION(OBJECT_ID) LIKE '%CreatedDate%';
person Akash KC    schedule 23.10.2013

Вы можете использовать ApexSQL Search, это бесплатная надстройка SSMS и Visual Studio, которая может отображать все объекты, которые ссылаются на определенный столбец таблицы. Он также может находить данные, хранящиеся в таблицах и представлениях. Вы можете легко отфильтровать результаты, чтобы показать определенный тип объекта базы данных, который ссылается на столбец.

введите описание изображения здесь

Заявление об ограничении ответственности: я работаю в ApexSQL инженером службы поддержки

person Milena Petrovic    schedule 23.10.2013
comment
Это дает не только столбец с именем FirstName в конкретном SP, но и в любом SP. Это нормально, пока одно и то же имя столбца не используется в нескольких таблицах, представлениях и т. Д. Я не знаю инструмента, который мог бы найти каждое место, на которое ссылается конкретный столбец. - person galmok; 18.06.2015

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

В приведенном ниже сценарии сначала перечислены таблицы / представления, содержащие имя столбца, который вы ищете, а затем исходный код хранимых процедур, в котором находится столбец. Он отображает результат в одной таблице, в которой различаются БАЗОВАЯ ТАБЛИЦА, ПРОСМОТР и ПРОЦЕДУРА, и (необязательно) исходный код во второй таблице:

DECLARE @SearchFor nvarchar(max)='%CustomerID%' -- search for this string
DECLARE @SearchSP bit = 1 -- 1=search in SPs as well
DECLARE @DisplaySPSource bit = 1 -- 1=display SP source code

-- tables
if (@SearchSP=1) begin  
  (
  select '['+c.table_Schema+'].['+c.table_Name+'].['+c.column_name+']' [schema_object], 
            t.table_type 
  from information_schema.columns c
  left join information_schema.Tables t on c.table_name=t.table_name
  where column_name like @SearchFor 
  union
  select '['+routine_Schema+'].['+routine_Name+']' [schema_object], 
         'PROCEDURE' as table_type from information_schema.routines
  where routine_definition like @SearchFor
        and routine_type='procedure'
  )
  order by table_type, schema_object
end else begin
  select '['+c.table_Schema+'].['+c.table_Name+'].['+c.column_name+']' [schema_object], 
         t.table_type 
  from information_schema.columns c
  left join information_schema.Tables t on c.table_name=t.table_name
  where column_name like @SearchFor 
  order by c.table_Name, c.column_name
end     
-- stored procedure (source listing)
if (@SearchSP=1) begin      
    if (@DisplaySPSource=1) begin
      select '['+routine_Schema+'].['+routine_Name+']' [schema.sp], routine_definition 
      from information_schema.routines
      where routine_definition like @SearchFor
      and routine_type='procedure'
      order by routine_name
    end
end

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

Обратите внимание, что вы можете установить @DisplaySPSource на 0, если вы просто хотите отображать имена SP, и если вы просто ищете таблицы / представления, но не для SP, вы можете установить @SearchSP на 0.

Пример результата (найдите CustomerID в базе данных Northwind, результаты отображаются через LinqPad):

Пример результата

Обратите внимание, что я проверил этот сценарий с помощью тестового представления dbo.TestOrders, и он обнаружил CustomerID в этом представлении, хотя c.* использовался в операторе SELECT (указанная таблица Customers содержит CustomerID, и, следовательно, представление показывает это столбец).


Примечание для пользователей LinqPad: в C # вы можете использовать dc.ExecuteQueryDynamic(sqlQueryStr, new object[] {... parameters ...} ).Dump(); и иметь параметры как @p0 ... @pn внутри строки запроса. Затем вы можете написать статический класс расширения и сохранить его в разделе Мои расширения для использования в ваших запросах LinqPad. Контекст данных может быть передан из окна запроса как DataContextBase dc через параметр, то есть public static void SearchDialog(this DataContextBase dc, string searchString = "%") внутри общедоступного статического класса расширения (в LinqPad 6 это DataContext). Затем вы можете переписать приведенный выше SQL-запрос как строку с параметрами и вызвать ее из контекста C #.

person Matt    schedule 26.06.2017
comment
Спасибо за большие усилия. Практически идеально. FYI - он не возвращает те SP, на которые есть ссылка column в insert into заявлении. Я нашел этот ответ более точным, stackoverflow.com/a/8757152/9695286. - person Karan; 23.04.2021
comment
@Karan - Я пробовал упомянутое вами решение, но оно не дает результатов. Я оставил там комментарий. - person Matt; 28.04.2021

попробуй это..

SELECT Name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%CreatedDate%'
GO

или вы можете создать сценарии всех процедур и искать оттуда.

person Nitu Bansal    schedule 23.10.2013

у меня была та же проблема, и я обнаружил, что Microsoft имеет systable, который показывает зависимости.

SELECT 
    referenced_id
    , referenced_entity_name AS table_name
    , referenced_minor_name as column_name
    , is_all_columns_found
FROM sys.dm_sql_referenced_entities ('dbo.Proc1', 'OBJECT'); 

И это работает как с Views, так и с Triggers.

person Rafa Barragan    schedule 14.06.2018

Вы можете использовать приведенный ниже запрос для определения значений. Но имейте в виду, что это не даст вам результатов для зашифрованной хранимой процедуры.

SELECT DISTINCT OBJECT_NAME(comments.id) OBJECT_NAME
    ,objects.type_desc
FROM syscomments comments
    ,sys.objects objects
WHERE comments.id = objects.object_id
    AND TEXT LIKE '%CreatedDate%'
ORDER BY 1
person Gopakumar N.Kurup    schedule 25.07.2016

- Искать по всем объектам

SELECT OBJECT_NAME(OBJECT_ID),
definition
FROM sys.sql_modules
WHERE definition LIKE '%' + 'ColumnName' + '%'
GO

- Искать только в хранимой процедуре

SELECT DISTINCT OBJECT_NAME(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'ColumnName' + '%'
GO
person Raj    schedule 09.06.2020