如何获取SQL调用者的SPID

时间:2017-04-13 15:18:06

标签: sql-server triggers audit-logging

我有一个多用户应用程序,它对SQL进行各种调用以更改各种表中的值。其中一些表具有触发器来审计更改。我在触发器中有代码,它尝试匹配由@@ SPID返回的SPID值,以及用户在注册数据库访问(登录)时存储的SPID值。

但是,我的测试显示,至少在某些时候,触发器运行时的SPID与先前保存的SPID不同。如何获得导致触发器运行的DB更改的连接的SPID?或者如果不是SPID,那么一些值可以相当可靠地识别出进行更改的当前活动的SQL连接?

这适用于中期调试,不打算成为永久性生产代码的一部分,但必须在实时系统上运行数天到数周。

2 个答案:

答案 0 :(得分:1)

您可以使用SQL Server函数public String serverToString() { String str; Thread t = new Thread(new Runnable() { public void run() { try { URL url = new URL("http://myIP/test.txt"); BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); str = in.readLine(); in.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Throwable th) { th.printStackTrace(); } } }); t.start(); return str; } 而不是使用@@SPID,该函数返回首次连接到该会话中SQL Server实例的登录标识。

答案 1 :(得分:0)

对于整个用户会话,SPID将与其他用户未共享的持久数据库连接相同。我不知道SPID将为审计提供多少价值,但似乎您正在寻找一种方法来将数据库更新活动与特定用户会话实例相关联。如果您使用服务凭证而不是最终用户的服务凭证进行数据库连接,则ORIGINAL_LOGIN将无法帮助进行审核。

您可以在CONTEXT_INFO或SESSION_CONTEXT()中存储会话标识符(例如guid),具体取决于您的SQL版本以供触发器代码使用。有关代码示例,请参阅How to add custom attributes to SQL connection string?