简体   繁体   English

每次查询数据库时如何执行存储过程

[英]How to execute a stored procedure every time a database is queried

Is there a way to execute a stored procedure every time a database is queried? 有没有一种方法可以在每次查询数据库时执行存储过程? I'm running SQL Server 2012 我正在运行SQL Server 2012

I want to be able to do something like the following: 我希望能够执行以下操作:

I have database MyDB containing tables Table1 and Table2. 我有包含表Table1和Table2的数据库MyDB。 I've deprecated Table1, and now every time someone runs any select statement against Table1 (eg SELECT * FROM Table1 ) I want to call a certain stored procedure that will log a message saying Table1 was accessed, so that I know some code is still accessing an old table and can go and remove that dependency. 我不推荐使用Table1,现在每次有人对Table1运行任何select语句(例如SELECT * FROM Table1 )时,我都想调用某个存储过程,该过程将记录一条消息,指出已访问Table1,因此我知道某些代码仍然存在访问旧表并可以删除该依赖项。

Is this possible? 这可能吗?

When I want to do something similar to what you are talking-about, I have used a View. 当我想做与您正在谈论的事情类似的事情时,我使用了一个视图。 (eg. Rename the table from dbo.Table1 to dbo.Table1_Orig and create a View like dbo.Table1, which is a wrapper around the table and includes a SP call or inline-function or equiv). (例如,将表从dbo.Table1重命名为dbo.Table1_Orig并创建一个类似于dbo.Table1的视图,该视图是表的包装器,并包含SP调用或内联函数或等效项。) Views can behave like a table and often seem transparent to a user/app. 视图的行为类似于表,并且通常对于用户/应用程序而言是透明的。

Otherwise, if your server is not really busy, you might want to consider using the SQL profiler, with a filter for that specific table, so it doesn't record gigs of queries. 否则,如果您的服务器不是很忙,则可能要考虑使用带有特定表过滤器的SQL事件探查器,因此它不会记录查询的演出。 It will add some overhead onto a server (5%) but otherwise, it is pretty unobtrusive and easy to turn on/off. 它将为服务器增加一些开销(5%),否则,它不会太引人注目并且易于打开/关闭。 Some people are really wary of leaving Profiler on for very long, and some companies forbid pointing Profiler at a production DB. 有些人真的很警惕将Profiler长时间打开,而有些公司则禁止将Profiler指向生产数据库。 So be really careful if you try it. 因此,请务必小心。 Keep an eye on it. 注意它。 You probably don't want to just leave it running for a few months. 您可能不想只让它运行几个月。 That would be evil. 那将是邪恶的。

I can think of one way to do what you want, but its pretty nasty, so as an alternative: 我可以想到一种做您想要的方法,但是它很讨厌,因此可以选择:

I'm assuming however that Table2 is effectively a replacement for Table1? 但是我假设Table2实际上是Table1的替代品?

In which case, would it be possible to simply drop Table1 and replace it with a view of the same name that transforms Table2 into the shape of the original Table1? 在这种情况下,是否可以简单地删除Table1并用具有相同名称的视图替换它,以将Table2转换为原始Table1的形状?

That way, you wouldn't need to log a message, since any code you have missed will effectively be accessing the correct table by virtue of the view... 这样,您就无需记录消息,因为您遗漏的任何代码都将通过视图有效地访问正确的表...

If that is no good for you, then here is my pretty hacky answer. 如果这对您不利,那么这是我的简单答案。 It relies on you enabling xp_cmdshell, and uses that as a hack to get around functions not being allowed side effects: 它依赖于您启用xp_cmdshell,并将其用作破解绕过不允许的副作用的功能:

1) Enable xp_cmdshell: 1)启用xp_cmdshell:

EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO

2) Rename Table1 to something else, say Deprecated_Table1 2)将Table1重命名为其他名称,例如Deprecated_Table1

3) Create a function that returns the data from Table1, and also logs a message to your log: 3)创建一个函数,该函数返回Table1中的数据,并将一条消息记录到您的日志中:

CREATE FUNCTION GetTable1()
RETURNS @Table1 TABLE
(
    ID int
)
AS
BEGIN
    DECLARE @sql varchar(3000)
    DECLARE @cmd varchar(4000)

    SELECT @sql = 'INSERT INTO MyLog Values(''Oops a daisy'')'
    SELECT @cmd = 'sqlcmd -S ' + @@servername + ' -d ' + db_name() + ' -Q "' + @sql + '"'

    EXEC master..xp_cmdshell @cmd, 'no_output'

    INSERT INTO @Table1
    SELECT ID FROM Deprecated_Table1

    RETURN
END

4) Create a view called Table1 that your legacy code will access, that calls the above function, and thus logs a message: 4)创建一个名为Table1的视图,您的旧代码将访问该视图,该视图调用上述函数,从而记录一条消息:

CREATE VIEW Table1 AS SELECT * FROM GetTable1()

Its deeply horrible, but since I guess this is just a temporary measure while you find all of the code you've missed, maybe it'll help you... 它非常可怕,但是由于我想这只是您找到所有错过的代码时的临时措施,因此也许会对您有所帮助...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM