Има ли начин да получите всички съхранени процедури, които могат да актуализират конкретна колона в SQL?

Имам поле в таблица, което неочаквано промени стойността си. Ясно е, че съхранена процедура е причинила това (вече претърсих няколкото задействания, които използваме, и никое влизане няма разрешения за актуализиране на която и да е таблица в нашата база данни) и съм в процес на намиране кой го е направил.

Ако бях да речем във Visual Studio, просто щях да направя „Намиране на всички препратки“ в полето и задачата щеше да е лесна.

Има ли еквивалентен инструмент за SQL? Знам за функцията „намиране на зависимости на обекти“ на SSMS, но това ще върне само съхранените процедури (и изгледи), използвайки таблицата, а не конкретното поле. (и за съжаление моята таблица е обединена в буквално хиляди SQL заявки)

Името на колоната е „Активно“, така че извършването на текстово търсене в моята схема на база данни също няма да помогне много (имам стотици таблици с такова поле)

Така че основно двете опции, които виждам, са:

  • писане на сложен регулярен израз, за ​​да съответства на актуализациите. Писането на такъв регулярен израз вероятно е огромна задача (заради всички тънкости на синтаксиса на SQL).
  • използвайки инструмент, който прави точно това.

Знаете ли за такъв инструмент (или такъв регулярен израз, или друг начин да направите това)?


person Brann    schedule 24.02.2011    source източник
comment
Ясно е, че съхранена процедура е причинила това - има много клишета относно предположенията, повечето от които вероятно биха маркирали коментара ми.   -  person Damien_The_Unbeliever    schedule 24.02.2011
comment
Прав си. Добавих повече информация за това (по принцип вече претърсих няколкото тригера, които използваме, и нито едно влизане няма достъп за запис в никоя таблица)   -  person Brann    schedule 24.02.2011
comment
Това, което можете да направите, е да се ограничите до пресечната точка на SQL модули, съдържащи UPDATE, TableName и Active. Това вероятно ще го стесни доколкото можете.   -  person Cade Roux    schedule 24.02.2011


Отговори (6)


Защо ви е ясно, че съхранена процедура променя стойността? Отказали ли сте директен достъп до таблица на всички влизания в базата данни? Целият ви достъп до базата данни ограничен ли е до съхранени процедури? Ако е така, би трябвало да е сравнително прост въпрос за търсене в съхранените процедури, които зависят от тази таблица, и проверката им.

Можете да използвате тригер, за да проследите промяната в колона. Използвал съм тригери, генерирани от AutoAudit, за да мога да проследявам промените.

Предимството на тригера е, че той е на ниво таблица и е част от схемата на базата данни, независимо от това как се изискват модификации на таблицата и независимо от механизма за свързване - ODBC/ADO/SP/Agent Job/Access свързана таблица, и т.н.

person Cade Roux    schedule 24.02.2011
comment
Наистина, нито едно влизане няма достъп за запис в таблицата и ние не използваме тригери (актуализирах първоначалния си въпрос, за да изясня това). Съгласен съм, че някои тригери биха помогнали за този вид процес на отстраняване на грешки, но това няма да работи за проследяване на вече възникнали грешки. - person Brann; 24.02.2011
comment
и нещото с търсенето на всички процедури е, че имам стотици процедури в зависимост от тази таблица. Повечето от тези процедури имат заявки, свързващи тази таблица в полето Active=1. - person Brann; 24.02.2011
comment
@Brann Няма лесен начин. Ако вашите SP имат конвенция за именуване, трябва да отметнете само тези, които са актуализации. Това, което ми харесва да виждам, са основни CRUD SP за всяка таблица, докладващи SP, които комбинират много таблици (но никога INSERT/UPDATE) и след това някои пакетни или бизнес/транзакционни SP, които извършват групови операции или многоетапни операции (превъртане на инвентар или нещо подобно така). Очевидно, ако това се случва на място, където не трябва, всички конвенции в света няма да помогнат. - person Cade Roux; 24.02.2011
comment
@Brann Нещо, което да помогне с многото Active = 1 (погледнато назад) филтрирани съединявания, би било да обвиете това в ActiveWhatever изглед и винаги да се присъедините към това вместо това. Но този вид рефакторинг отнема известно време. - person Cade Roux; 24.02.2011

Един подход на "бедния човек" към това би бил да изтриете колоната от копие на вашата база данни и след това да се опитате да намерите съхранените процедури, които вече не работят. Има статия за проект за код, която твърди, че може да провери всички съхранени процедури вместо вас , или може да сте в състояние да вземете концепцията, обяснена там, и да я изградите изцяло като T-SQL скрипт, който изплюва T-SQL скрипт, който след това ще направи грешка на подходящите места.


От коментар - в този случай заменете колоната Active с изчислена колона. напр.:

ALTER TABLE TableName DROP COLUMN Active
GO
ALTER TABLE TableName ADD Active as CAST(1 as bit)

(Или какъвто и да е подходящият тип данни). Това ще прекъсне DML изразите, докато SELECTs ще продължат да работят.

person Damien_The_Unbeliever    schedule 24.02.2011
comment
Важното е, че това ще наруши всички процедури, разчитащи на достъп за ЧЕТЕНЕ до моята колона. Опитвам се да намеря само процедурите, изискващи достъп за запис. - person Brann; 24.02.2011
comment
използването на изчислени колони е страхотна идея! +1 от мен - person Brann; 24.02.2011

SQL Prompt 5 има функция за зависимости на колони, която може да работи за вас.

person David Atkinson    schedule 24.02.2011

Вижте sys.sql_dependencies. Нещо като

select object_name(o.object_id)
from sys.sql_dependencies sd
inner join sys.objects o
   on sd.referenced_major_id = o.object_id
inner join sys.columns c
   on o.object_id = c.object_id
   and sd.referenced_minor_id = c.column_id
where o.name = 'your_table_here'
   and c.name = 'your_column_here'

Вероятно е добра идея да извикате sp_refreshsqlmodule на всички ваши съхранени процедури, за да сте сигурни, че sys.sql_dependencies е актуален. Освен това внимавайте, че този метод няма да улови динамичен sql, така че ако това ви притеснява, ще трябва да намерите друг метод.

person Ben Thul    schedule 24.02.2011
comment

Имах същия проблем, когато добавя допълнителен бутон без идентификатор, това изключение се появява в дневника, но когато добавя идентификатора към новия бутон, изключението изчезва. Опитайте да поставите идентификаторите на компонентите, които генерират грешката.

- person catfood; 24.05.2012

Опитайте тази:

SELECT DISTINCT so.name
FROM sys.syscomments sc
INNER JOIN sys.objects so on sc.id=so.object_id
WHERE sc.text LIKE '%colToSearchFor =%'

Това предполага, че има интервал между името на колоната и знака за равенство, така че ще трябва да го стартирате без интервал или с повече интервали/табулации и т.н. Все пак е по-добре от нищо

person Trent    schedule 18.03.2013

Redgate предоставя SQL инструмент за търсене, така че можете да търсите вашия sql код в базата данни за името на колоната, което може да е отговор. Или това, или щракнете с десния бутон и скриптирайте цялата си база данни във файл и намирането в този файл.

Аз също не бих го ограничил до SPs. Колко пъти съм имал този проблем и се е свеждал до забравен тригер (grr тригери...)...

person Paddy    schedule 24.02.2011