关闭 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,如下:

    其方法调用如下图:

    如有问题欢迎指正

    上一篇返回首页 下一篇

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

    别人在看

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    小米路由器买哪款?Miwifi热门路由器型号对比分析

    IT头条

    Synology 对 Office 套件进行重大 AI 更新,增强私有云的生产力和安全性

    01:43

    StorONE 的高效平台将 Storage Guardian 数据中心占用空间减少 80%

    11:03

    年赚千亿的印度能源巨头Nayara 云服务瘫痪,被微软卡了一下脖子

    12:54

    国产6nm GPU新突破!砺算科技官宣:自研TrueGPU架构7月26日发布

    01:57

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    技术热点

    如何删除自带的不常用应用为windows 7减负

    MySQL中多表删除方法

    改进的二值图像像素标记算法及程序实现

    windows 7 32位系统下手动修改磁盘属性例如M盘修改为F盘

    windows 7中怎么样在家庭组互传文件

    Linux应用集成MySQL数据库访问技巧

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

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