在 CLR 触发器中访问 .NET 应用程序变量
Access to .NET application variable in CLR trigger
我在 C# .NET 中创建了一个小应用程序,我在其中初始化并分配了一些 public variable/static 变量(例如我的登录用户 ID)。现在一些数据库操作发生在这个应用程序中。我在一个单独的项目 (.dll) 中创建了 CLR 触发器,该项目记录了登录用户所做的数据库更改 - 该位工作正常。现在我想要在该数据库上执行操作的用户标识,并希望将其存储在我的 运行 应用程序中的 public 变量中。
有什么方法可以访问 CLR 触发器中的 .NET 应用程序变量 class?
Is there any way to access a .NET application variable in the CLR trigger class?
没有。也没有任何方法可以访问常规 T-SQL 存储过程/函数/触发器之间的局部变量。如果您想将信息从应用程序层传递到触发器,您可以使用与 T-SQL 存储过程/即席查询相同的选项:
通过 SET CONTEXT_INFO 将值存储在会话中,这是一种 VARBINARY(128)
数据类型。您可以通过 CONTEXT_INFO()
函数读取该值。此值在 sys.dm_exec_sessions
DMV 中也是可读的。如果一个进程没有设置该值,它将是 NULL
。如果您已经在使用 CONTEXT_INFO
存储其他信息,则此方法无效。
创建一个本地临时文件 table(键入每个 session_id
/ SPID)并将值存储在其中。然后在每个触发器中只从它 SELECT
。如果一个进程没有创建本地临时文件 table,你会在 SELECT
查询中得到一个错误(所以你可能会把它包装在一个 IF OBJECT_ID(N'tempdb..#tempTableName') IS NOT NULL
结构中。
如果使用 SQL Server 2016(或更新版本),您可以使用新的 SESSION_CONTEXT 散列 table.
这三种情况都是在app层打开SqlConnection
后,通过ExecuteNonQuery()
执行SQL语句完成以上操作,然后再进行其他操作.然后,在 SQLCLR 触发器中,第一步是使用 Context Connection = true;
连接到当前进程/会话并获取值。
此外,上述所有三种方法都允许 T-SQL 代码也将此审计信息传递给触发器,无论它们是 T-SQL 还是 SQLCLR。这很重要,因为应用程序是否会对发生的 100% 的更改负责是值得怀疑的。通常人们有 SQL 代理作业 and/or 临时支持/发布查询,如果需要在应用程序层中分配变量,这些更改将无法被跟踪。
I had assigned a value in CLR trigger class static variable (e.g _userid), but this value not getting while calling another static method in same class (which is called by me from trigger). why? If CLR class is called and assess by MSSQL server process, same class is also assessable with my app too.
不仅 SQL 服务器与您的应用程序使用的应用程序域不同,它们也是完全不同的 CLR 主机。
无论哪种方式,您都不希望静态变量起作用,因为所有 SQL 服务器会话将共享一个静态变量,因此会同时覆盖其他会话 运行 ;-) .
我在 C# .NET 中创建了一个小应用程序,我在其中初始化并分配了一些 public variable/static 变量(例如我的登录用户 ID)。现在一些数据库操作发生在这个应用程序中。我在一个单独的项目 (.dll) 中创建了 CLR 触发器,该项目记录了登录用户所做的数据库更改 - 该位工作正常。现在我想要在该数据库上执行操作的用户标识,并希望将其存储在我的 运行 应用程序中的 public 变量中。
有什么方法可以访问 CLR 触发器中的 .NET 应用程序变量 class?
Is there any way to access a .NET application variable in the CLR trigger class?
没有。也没有任何方法可以访问常规 T-SQL 存储过程/函数/触发器之间的局部变量。如果您想将信息从应用程序层传递到触发器,您可以使用与 T-SQL 存储过程/即席查询相同的选项:
通过 SET CONTEXT_INFO 将值存储在会话中,这是一种
VARBINARY(128)
数据类型。您可以通过CONTEXT_INFO()
函数读取该值。此值在sys.dm_exec_sessions
DMV 中也是可读的。如果一个进程没有设置该值,它将是NULL
。如果您已经在使用CONTEXT_INFO
存储其他信息,则此方法无效。创建一个本地临时文件 table(键入每个
session_id
/ SPID)并将值存储在其中。然后在每个触发器中只从它SELECT
。如果一个进程没有创建本地临时文件 table,你会在SELECT
查询中得到一个错误(所以你可能会把它包装在一个IF OBJECT_ID(N'tempdb..#tempTableName') IS NOT NULL
结构中。如果使用 SQL Server 2016(或更新版本),您可以使用新的 SESSION_CONTEXT 散列 table.
这三种情况都是在app层打开SqlConnection
后,通过ExecuteNonQuery()
执行SQL语句完成以上操作,然后再进行其他操作.然后,在 SQLCLR 触发器中,第一步是使用 Context Connection = true;
连接到当前进程/会话并获取值。
此外,上述所有三种方法都允许 T-SQL 代码也将此审计信息传递给触发器,无论它们是 T-SQL 还是 SQLCLR。这很重要,因为应用程序是否会对发生的 100% 的更改负责是值得怀疑的。通常人们有 SQL 代理作业 and/or 临时支持/发布查询,如果需要在应用程序层中分配变量,这些更改将无法被跟踪。
I had assigned a value in CLR trigger class static variable (e.g _userid), but this value not getting while calling another static method in same class (which is called by me from trigger). why? If CLR class is called and assess by MSSQL server process, same class is also assessable with my app too.
不仅 SQL 服务器与您的应用程序使用的应用程序域不同,它们也是完全不同的 CLR 主机。
无论哪种方式,您都不希望静态变量起作用,因为所有 SQL 服务器会话将共享一个静态变量,因此会同时覆盖其他会话 运行 ;-) .