关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » SQL Server »让SQL Server调用DLL文件的方法详解

    让SQL Server调用DLL文件的方法详解

    2014-09-24 00:00:00 出处:ITJS
    分享

    背景

    在处理数据或者分析数据时,我们常常需要加入一定的逻辑,该些处理逻辑有些sql是可以支持,有些逻辑SQL则无能为力,在这种情况下,大多数人都会编写相关的程序来处理成自己想要的数据,但每次处理相同逻辑时,都需要运行一次程序非常麻烦。

    案例

    IE地址栏上的地址在记入日志表中时,其数据是通过编码的,如果我们想要看到明文,则需要相应的解码,可以用SQL语句来实现,如:

    CREATE FUNCTION FN_URLDecode  
    (  
     @Str VARCHAR(8000)
    )  
    RETURNS VARCHAR(8000)  
    AS  
    BEGIN  
      DECLARE @Position  INT;          --'%'字符所在位置  
      DECLARE @Chr       CHAR(16);     --字符常量  
      DECLARE @Pattern   CHAR(21);  
      DECLARE @ParseStr  VARCHAR(8000);--解码后的字符串  
      DECLARE @Hex       UNIQUEIDENTIFIER;--定义16进制模板,因为GUID方便转为BYTE  
      DECLARE @CurrWord  INT        ;--当前字  
      DECLARE @BitsCount INT        ;--当前解码位数  
      DECLARE @HightByte TINYINT;--高位字节  
      DECLARE @LowByte   TINYINT;--低位字节  
    
      SET     @Chr = '0123456789abcdef';  
      SET     @Pattern = '%[%][a-f0-9][a-f0-9]%';  
      SET     @ParseStr=@Str;  
      SET     @Hex= '00000000-0000-0000-0000-000000000000';  
      SET     @CurrWord=0;  
      SET     @BitsCount=0;  
      SET     @HightByte=0;  
      SET     @LowByte=0;  
    
      IF (@Str IS NOT NULL OR @Str<>'')  
       BEGIN  
         SET    @Position = PATINDEX(@Pattern, @ParseStr);
         WHILE @Position>0  
          BEGIN  
            SET @Hex=STUFF(@Hex,7,2,LEFT(RIGHT(@ParseStr,len(@ParseStr) - @Position),2));  
            SET @HightByte=CAST(CAST(@Hex AS BINARY(1)) AS INT);  
    
            IF (@HightByte & 127=@HightByte)  
             BEGIN  
               SET @CurrWord=@HightByte;  
               SET @BitsCount=1;  
             END  
    
            IF (@HightByte & 192=192)  
             BEGIN
               SET @CurrWord=@HightByte & 31 ;  
               SET @BitsCount=2;  
             END  
    
            IF (@HightByte & 224=224)  
             BEGIN 
                SET @CurrWord = @HightByte & 15  
                SET @BitsCount = 3    
             END  
    
            IF (@HightByte & 240=240)  
             BEGIN
                SET @CurrWord = @HightByte & 7  
                SET @BitsCount = 4    
             END  
    
            DECLARE @Index INT;          
            DECLARE @NEWCHAR NVARCHAR(2);  
            SET @Index=1;  
            SET @NEWCHAR='';  
            WHILE @Index<@BitsCount  
             BEGIN  
                  IF (LEN(@ParseStr)-@Position-3*@Index)<0  
                   BEGIN  
                       SET @ParseStr=@Str ;     
                       SET @Position=0;  
                       BREAK;                
                   END  
                SET @NEWCHAR = LEFT(RIGHT(@ParseStr,LEN(@ParseStr) - @Position - 3* @Index),2);     
                IF @NEWCHAR NOT LIKE '[a-f0-9][a-f0-9]'  
                 BEGIN  
                    SET @ParseStr = @Str  
                    SET @Position=0;
                    BREAK;  
                 END      
    
                SET @Hex = STUFF(@Hex, 7, 2, @NEWCHAR)        
    
                SET @LowByte = CAST(CAST(@Hex AS BINARY(1)) AS INT);  
    
                IF @LowByte&192=192  
                BEGIN  
                    SET @ParseStr = @Str  
                    SET @Position=0;
                    BREAK;  
                END   
    
                SET @CurrWord = (@CurrWord * 64) | (@LowByte & 63)                
                SET @Index =@Index+ 1                                                  
             END                                     
    
             IF @BitsCount > 1             
              SET @ParseStr = STUFF(@ParseStr, @Position, 3*(@BitsCount), NCHAR(@CurrWord))  
             ELSE   
              BEGIN  
                set @ParseStr = STUFF(@ParseStr, @Position, 2, NCHAR(@CurrWord))  
                set @ParseStr = STUFF(@ParseStr, @Position+1, 1, N'')         
              END   
            SET  @Position = PATINDEX(@Pattern, @ParseStr);  
          END  
       END  
       RETURN @ParseStr;  
    END

    其执行结果如下:

    利用SQL不仅需要写很复杂的函数,如果需要加入其他操作时,也需要花大量时间来修改。

    如果采用程序处理此类问题那将简单的多,如下:

    using System.Text;
    using System.Web;
    
    namespace UrlDecode
    {
        /*code 释迦苦僧*/
        public class UrlDll
        {
            /// <summary>
            /// 获取URL的值
            /// </summary> 
            public static string GetUrlPara(string url, string key)
            {
                key = key + "=";
                string[] strs = url.Split('&');
                foreach (string str in strs)
                {
                    if (str.IndexOf(key) >= 0)
                    {
                        string sub = str.Substring(str.IndexOf(key) + key.Length, str.Length - str.IndexOf(key) - key.Length);
                        string sub2 = MyUrlDeCode(sub, null);
                        if (sub2.IndexOf(' ') >= 0)
                        {
                            sub2 = sub2.Substring(0, sub2.IndexOf(' '));
                        }
                        return sub2;
                    }
                }
                return string.Empty;
            }
            /// <summary>
            /// 解码URL.
            /// </summary>
            /// <param name="encoding">null为自动选择编码</param>
            /// <param name="str"></param>
            /// <returns></returns>
            public static string MyUrlDeCode(string str, Encoding encoding)
            {
                if (encoding == null)
                {
                    Encoding utf8 = Encoding.UTF8;
                    //首先用utf8进行解码                     
                    string code = HttpUtility.UrlDecode(str, utf8);
                    string tempcode = code;
                    if (code.IndexOf(' ') >= 0)
                    {
                        tempcode = code.Substring(0, code.IndexOf(' '));
                    }
                    //将已经解码的字符再次进行编码.
                    string encode = HttpUtility.UrlEncode(tempcode, utf8).ToUpper();
                    if (encode.IndexOf('+') >= 0)
                    {
                        encode = encode.Substring(0, encode.IndexOf('+'));
                    }
                    if (str.ToUpper().Contains(encode.ToUpper()))
                        encoding = Encoding.UTF8;
                    else
                        encoding = Encoding.GetEncoding("gb2312");
                }
                string encodeing = HttpUtility.UrlDecode(str, encoding);
                if (encodeing.Contains("%") && encodeing.Length > 8)
                {
                    return MyUrlDeCode2(encodeing, null);
                }
                return encodeing;
            }
            public static string MyUrlDeCode2(string str, Encoding encoding)
            {
                if (encoding == null)
                {
                    Encoding utf8 = Encoding.UTF8;
                    //首先用utf-8进行解码                     
                    string code = HttpUtility.UrlDecode(str.ToUpper(), utf8);
                    //将已经解码的字符再次进行编码.
                    string encode = HttpUtility.UrlEncode(code, utf8).ToUpper();
                    if (str.ToUpper() == encode)
                        encoding = Encoding.UTF8;
                    else
                        encoding = Encoding.GetEncoding("gb2312");
                }
                return HttpUtility.UrlDecode(str, encoding);
            }
        }
    }

    在SQL中调用此类的方法,需要将其封装在DLL中,如下:

    1.将类库设置为.NET Framework2.0 如下:

    2.在Release下编译成dll

    3.将dll添加到SQL Server中

    --code 释迦苦僧
    --修改系统配置的存储过程当设置 show advanced options 参数为 1 时,才允许修改系统配置中的某些高级选相!!系统中这些高级选项默认是不允许修改
    exec sp_configure 'show advanced options','1'
    go
    --重新配置 就是用来更新使用sp_configure 系统存储过程更改的配置选项的当前配置值
    reconfigure
    go
    --建立可信赖
    alter database Auth3 set trustworthy on
    go
    --添加关联DLL
    CREATE ASSEMBLY [System.Web] FROM 'C:WindowsMicrosoft.NETFrameworkv2.0.50727System.Web.dll' WITH PERMISSION_SET = UNSAFE
    go
    --开启CLR集成
    EXEC sp_configure 'clr enabled','1'
    go
    --重新配置 就是用来更新使用sp_configure 系统存储过程更改的配置选项的当前配置值
    reconfigure
    --添加刚刚编译的DLL
    create assembly SqlUrlDecode from  'D:Test VS ProjectUrlDllUrlDecodebinReleaseUrlDecode.dll'  
    go
    
    --创建函数
    CREATE FUNCTION dbo.FunUrlDecode
    ( 
    @url as nvarchar(500),
    @key as nvarchar(120) 
    )
    RETURNS nvarchar(200) 
    AS EXTERNAL NAME SqlUrlDecode.[UrlDecode.UrlDll].GetUrlPara
                   --Sql命名空间   dll命名空间 dll类 dll方法

    将dll添加成功后,我们可以在SQL SERVER 找到相关的Assembiles,如下:

    其方法调用如下图:

    如有问题欢迎指正

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    帝国CMS7.5编辑器上传图片取消宽高的三种方法

    帝国cms如何自动生成缩略图的实现方法

    Windows 12即将到来,将彻底改变人机交互

    帝国CMS 7.5忘记登陆账号密码怎么办?可以phpmyadmin中重置管理员密码

    帝国CMS 7.5 后台编辑器换行,修改回车键br换行为p标签

    Windows 11 版本与 Windows 10比较,新功能一览

    Windows 11激活产品密钥收集及专业版激活方法

    IT头条

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    严重缩水!NVIDIA将推中国特供RTX 5090 DD:只剩24GB显存

    00:17

    无线路由大厂 TP-Link突然大裁员:补偿N+3

    02:39

    Meta 千万美金招募AI高级人才

    00:22

    技术热点

    微软已修复windows 7/windows 8.1媒体中心严重漏洞 用户可下载安

    卸载MySQL数据库,用rpm如何实现

    windows 7中使用网上银行或支付宝支付时总是打不开支付页面

    一致性哈希算法原理设计

    MySQL数字类型中的三种常用种类

    如何解决SQL Server中传入select语句in范围参数

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。