代码之家  ›  专栏  ›  技术社区  ›  John K

从.NET CLR UDF调用T-SQL内置函数的有效方法?

  •  3
  • John K  · 技术社区  · 6 年前

    From a CLR UDF (C# syntax) 或多或少直接处理

    // Programming .inside NET CLR UDF:
    
    // Is there a more efficient way than this command?
    SqlCommand cmd... = new SqlCommand( ...'SELECT EncryptByKey(@Param, @Param2...) );
    cmd.Execute();
    

    如果该方法正在多次运行。我想这取决于创建UDF时.NETFramework类库中可用的SQLServer集成功能。

    考虑到API,这可能已经是最有效的方法了。我不知道。

    使用SQLServer2005。


    内置的示例

    我一直在使用的一个内置函数的示例就是SQL Server的 EncryptByKey(..)

    对安全数据库中的许多值和字段多次调用加密。当它被使用时,它经常被高度使用,不像其他一些函数只是偶尔被调用。

    select dbo.EncryptByKey(..) <&书信电报;SQL 服务器错误

    相反,它必须像这样被称为不合格

    select EncryptByKey(..) . <&书信电报;好啊

    如果在上面这样的CLR UDF中使用它,那么最好能更有效地调用它,因为它的使用非常普遍和稳定。

    1 回复  |  直到 15 年前
        1
  •  1
  •   Aaronaught    15 年前

    使用 SqlCommand 可能看起来效率很低,但实际上并非如此,因为所有命令都是在上下文连接上执行的。除非您是在一个紧密的循环中进行这项工作(在这种情况下,您可能应该考虑重新设计UDF),否则开销将是最小的;传统数据库访问所涉及的大部分开销往往是在建立连接和穿越网络时产生的,这两个方面在这里都不是问题。

    如果您只是担心需要编写的所有额外代码,请使用助手方法:

    public static TResult Execute<TResult>(SqlConnection connection, string cmdText)
    {
        using (SqlCommand cmd = new SqlCommand(cmdText, connection))
        {
            return (TResult)cmd.ExecuteScalar();
        }
    }
    

    public static byte[] EncryptByKey(SqlConnection connection,
        string keyName, string clearText)
    {
        return Execute<byte[]>(connection,
            string.Format("SELECT ENCRYPTBYKEY(KEY_GUID('{0}'), '{1}')"));
    }
    

    据我所知,没有比这更“有效”的方法了。您必须记住,您的CLR UDF并不是真正的“在”数据库连接中,它运行在它自己的AppDomain中,而AppDomain中已经注入了 SqlContext ,因此不存在对SQL语法的“直接”访问—您必须通过上下文连接实际发出这些命令,任何简化都只是语法上的糖分。

    如果你发现自己的频率很高,那么我会考虑在CLR UDF内做所有你想做的工作是否真的合适。CLR UDF的主要目的是 SQL Server中已有的功能。如果只是为了访问内置函数而进行过多的数据访问或执行过多的命令,这可能是一个迹象,表明您已经反转了依赖关系,最好编写一个普通的UDF,分支到几个实用程序CLR UDF。只是想一想。