【问题标题】:Get the SQL statement that invoked the CLR function获取调用 CLR 函数的 SQL 语句
【发布时间】:2026-02-17 19:35:02
【问题描述】:

是否可以从 SQL 正在执行的 CLR 函数中确定首先调用 CLR 函数的 SQL 语句。如果没有直接的方法,那么间接的方法呢,比如获取某种句柄标识符并返回并查询 SQL 或该信息的日志?

例子:

SQL 执行:

select * from genericTable1 join genericCLRfunction() f on genericTable1.col = f.col;

在调用 genericCLRfunction() 的 SQL 语句调用的 CLR 中,我希望得到一个字符串,等于:

"select * from genericTable1 join genericCLRfunction() f on genericTable1.col = f.col;"

【问题讨论】:

  • 您可以手动将整个 sql 作为字符串参数传递给 CLR 函数,尽管如果您的 CLR 函数被许多不同的 SQL 语句调用,那么维护起来会很麻烦。
  • 我有这个需求是因为我没有能力更新所有的 SQL 语句,有些是在 3rd 方软件中硬编码的,但我需要根据上下文更改我的函数的行为它被使用了。
  • 第三方软件有 SQL 调用你的 SQLCLR 函数,但你没有能力改变第三方调用你的函数的方式?
  • 第三方软件只是取了一个表名,并不知道是CLR函数。

标签: c# sql tsql sqlclr


【解决方案1】:

我现在实际上无法尝试,但有一种可能性。您可以像这样在 CLR 中获取会话 ID...

using (SqlConnection cn = new SqlConnection("context connection=true;"))
{
   cn.Open();
   SqlCommand cmd = new SqlCommand("SELECT @@SPID", cn);
   int spid = Convert.ToInt32(cmd.ExecuteScalar());
   cn.Close();
}

然后,尝试使用此 SO 问题的已接受答案中显示的查询...

List the queries running on SQL Server

【讨论】:

  • "SELECT * FROM sys.dm_exec_requests CROSS APPLY sys.dm_exec_sql_text(sql_handle)
  • 我的意思是:我首先尝试使用“SELECT sqlText.text, req.session_id FROM sys.dm_exec_requests req CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqlText WHERE req.session_id = @@SPID”结合你的第一个建议和您提供的链接中的信息,但结果有一半的时间是“SELECT sqlText.text, req.session_id FROM sys.dm_exec_requests req CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqlText WHERE req.session_id = @ @SPID”。所以我最终确保 SELECT 语句在不同的连接上运行,并使 @@SPID 传递到表函数中。