Существует функция SQL, которую я хотел бы удалить из базы данных SQL Server 2005, но сначала я хотел бы удостовериться, что нет никакого вызова ее. Я использовал функцию "View Dependencies" для удаления любой ссылки на него от базы данных. Однако могут быть веб-приложения или пакеты SSIS с помощью него.
Моя идея состояла в том, чтобы иметь функциональную вставку запись в контрольной таблице каждый раз, когда это назвали. Однако это будет иметь ограниченную ценность, если я также не буду знать вызывающую сторону. Там какой-либо путь состоит в том, чтобы определить, кто вызвал функцию?
попробуйте выполнить поиск по коду:
--declare and set a value of @SearchValue to be your function name
SELECT DISTINCT
s.name+'.'+o.name AS Object_Name,o.type_desc
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id=o.object_id
INNER JOIN sys.schemas s ON o.schema_id=s.schema_id
WHERE m.definition Like '%'+@SearchValue+'%'
ORDER BY 1
, чтобы найти вызывающего абонента во время выполнения, вы можете попробовать использовать CONTEXT_INFO
--in the code chain doing the suspected function call:
DECLARE @CONTEXT_INFO varbinary(128)
,@Info varchar(128)
SET @Info='????'
SET @CONTEXT_INFO =CONVERT(varbinary(128),'InfoForFunction='+ISNULL(@Info,'')+REPLICATE(' ',128))
SET CONTEXT_INFO @CONTEXT_INFO
--after the suspected function call
SET CONTEXT_INFO 0x0 --reset CONTEXT_INFO
--here is the portion to put in the function:
DECLARE @Info varchar(128)
,@sCONTEXT_INFO varchar(128)
SET @sCONTEXT_INFO=CONVERT(varchar(128),CONTEXT_INFO())
IF LEFT(@sCONTEXT_INFO,15)='InfoForFunction='
BEGIN
SET @Info=RIGHT(RTRIM(@sCONTEXT_INFO),LEN(RTRIM(@sCONTEXT_INFO))-15)
END
--use the @Info
SELECT @Info,@sCONTEXT_INFO
, если вы поместите разные значения в @CONTEXT_INFO в разных местах, вы можете сузить круг тех, кто вызывает функцию , и уточняйте значение, пока не найдете его.
Вы можете вызвать расширенные хранимые процедуры из функции .
Вот несколько примеров:
Если у вас были правильные разрешения, теоретически вы могли бы вызвать расширенную хранимую процедуру из своей функции и сохранить такую информацию, как APP_NAME () и ORIGINAL_LOGIN ( ) в плоском файле или в разделе реестра.
Другой вариант - создать расширенную хранимую процедуру с с нуля .
Если все это вызывает слишком много проблем, я бы последовал ранним рекомендациям SQL Profiler или трассировки на стороне сервера .
Ниже приведен пример использования расширенной хранимой процедуры. Это использует xp_logevent для регистрации каждого экземпляра вызова функции в журнале приложения Windows.
Одним из недостатков этого метода является то, что если функция применяется к столбцу в запросе SELECT, она будет вызываться для каждой возвращаемой строки. Это означает, что вы можете быстро заполнить журнал.
Код:
USE [master]
GO
/* A security risk but will get the job done easily */
GRANT EXECUTE ON xp_logevent TO PUBLIC
GO
/* Test database */
USE [Sandbox]
GO
/* Test function which always returns 1 */
CREATE FUNCTION ufx_Function() RETURNS INT
AS
BEGIN
DECLARE
@msg VARCHAR(4000),
@login SYSNAME,
@app SYSNAME
/* Gather critical information */
SET @login = ORIGINAL_LOGIN()
SET @app = APP_NAME()
SET @msg = 'The function ufx_Function was executed by '
+ @login + ' using the application ' + @app
/* Log this event */
EXEC master.dbo.xp_logevent 60000, @msg, warning
/* Resume normal function */
RETURN 1
END
GO
/* Test */
SELECT dbo.ufx_Function()
В зависимости от вашей текущей модели безопасности. Мы используем пул соединений с одной учетной записью sql. У каждого приложения есть собственная учетная запись для подключения к базе данных. Если это так. Затем вы можете выполнить сеанс Sql Profiler, чтобы найти вызывающего эту функцию. Какая бы учетная запись ни вызывала функцию, она будет напрямую относиться к одному приложению.
Это работает для нас в том, как мы обрабатываем трафик Sql; Я надеюсь, что то же самое и с вами.
Вы можете попробовать использовать APP_NAME () и USER_NAME (). Он не даст вам подробностей (например, имя пакета SSIS), но может помочь.
Другой гораздо менее элегантный способ - использовать grep -R [имя функции] *
через исходный код. Это может или не может работать в зависимости от количества кода.
Это имеет то преимущество, что работает, даже если эта часть единственного используется очень нечасто, что было бы большой проблемой для вашей идеи таблицы аудита.
Это поможет вам узнать, вызывается ли это где-нибудь в вашей базе данных.
select object_name(id) from sys.syscomments where text like '%**<FunctionName>**%'
Вы можете запустить трассировку в профилировщике, чтобы увидеть, вызывается ли эта функция в течение недели (или того, что вы считаете безопасным окном).
Я думаю, что вы также можете использовать OPENROWSET для вызова SP, который ведет журнал в таблице, если вы включите специальные запросы.