设为首页 收藏本站
查看: 676|回复: 0

[经验分享] 如何更新Sql Server里的CLR程序集

[复制链接]

尚未签到

发表于 2015-6-28 15:32:35 | 显示全部楼层 |阅读模式
  Sql Server 2005/2008增加了对Clr的支持,开发者可以用.net语言如C#、VB.net等编写Sql Server的存储过程、函数。这样大大增强了Sql Server的功能,为编程开发带来了方便。怎样创建CLR存储过程网上的介绍文章已经很多了,本文不讨论了。
  
  作者在使用过程中遇到了这样的问题,就是程序集assembly的更新问题。在Sql Server中程序集不能修改,只能删了重建。见下图:
  
  

  
http://images.iyunv.com/cnblogs_com/edong/程序集修改.jpg接下来如果想用drop命令把它删掉,就会出现这个:   
  由于对象 'IsLegalDate' 引用了 'ZSqlExtend',DROP ASSEMBLY 失败。
  原来基于这个程序集肯定要建很多存储过程和函数,这些对象引用了这个程序集,DROP ASSEMBLY 失败。可以单击上图中“查看依赖关系”。
  怎么办呢?那只能把引用这个程序集的所有对象都删掉,这样一来工作量可就大了,而且重建程序集后还要建这些存储过程和函数。
  这些存储过程和函数也有可能被引用,也删不掉。
  这样我们更新程序集岂不是太麻烦了?笔者想出一个变通的办法,与广大网友交流。
  首先ZSqlExtend的代码如下,里面有一个IsLegalDate函数。用VS2008编译后的文件是ZSqlExtend.dll。
  using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
  namespace ZSqlExtend_NS
{
    public class ZSqlExtend_cls
    {
        [SqlFunction(DataAccess = DataAccessKind.Read)]
        public static bool IsLegalDate(int iyear, int imonth, int iday)
        {
            bool ild = false;
            try
            {
                DateTime newdate = new DateTime(iyear, imonth, iday);
                //smalldatetime范围1900-01-01 到 2079-06-06
                DateTime dMin = new DateTime(1900, 1, 1);
                DateTime dMax = new DateTime(2079, 6, 7);
                ild = newdate >= dMin && newdate < dMax;
            }
            catch
            {
                ild = false;
            }
            return ild;
        }
  }                            //END CLASS
  }
  根据这个dll文件在Sql Server中创建程序集和函数:
  create assembly ZSqlExtend
from 'E:\hs1\ZSqlExtend\bin\ZSqlExtend.dll' with permission_set = Safe;
go
  CREATE FUNCTION IsLegalDate
(@y int,@m int,@d int)
RETURNS bit
AS EXTERNAL NAME ZSqlExtend.[ZSqlExtend_NS.ZSqlExtend_cls].IsLegalDate;
go
  
  然后再建一个类库项目,比如我再做一个ZSqlExtend_dummy的类库项目,用VS2008编译后的文件是ZSqlExtend_dummy.dll,这个是ZSqlExtend.dll的代替品。
  把ZSqlExtend.dll的内容在这个再写一遍,不过这个是假的,所以可以写成这样:
  using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
  namespace ZSqlExtend_NS
{
    public class ZSqlExtend_cls
    {
        [SqlFunction(DataAccess = DataAccessKind.Read)]
        public static bool IsLegalDate(int iyear, int imonth, int iday)
        {
            return true;
        }
  }                            //END CLASS
  }
  把这个“假的”ZSqlExtend_dummy.dll也注册进Sql Server。
create assembly ZSqlExtend_dummy
from 'E:\hs1\ZSqlExtend_dummy\bin\ZSqlExtend_dummy.dll' with permission_set = Safe;
go    我们的第一步工作就做完了。现在我在项目ZSqlExtend里修改了IsLegalDate,需要重建程序集,就出现了本文一开始的情况。当然你可以先把IsLegalDate删掉,但是我不能这么做,因为很多表的计算字段和视图引用了IsLegalDate。所以我只能让IsLegalDate和程序集ZSqlExtend脱钩,然后将程序集ZSqlExtend删除重建。要想脱钩就得用那个
  ZSqlExtend_dummy了,因为它其中的函数签名和ZSqlExtend完全一样。
  函数IsLegalDate是不能删了,但我们可以修改它,把它改在别的程序集上。Sql Server中执行:
alter FUNCTION IsLegalDate
(@y int,@m int,@d int)
RETURNS bit
AS EXTERNAL NAME ZSqlExtend_dummy.[ZSqlExtend_NS.ZSqlExtend_cls].IsLegalDate;
go    
OK,此时程序集ZSqlExtend已经可以删除重建了,在Sql Server中运行:
  drop assembly ZSqlExtend;
  create assembly ZSqlExtend
from 'E:\hs1\ZSqlExtend\bin\ZSqlExtend.dll' with permission_set = Safe;
go
  当然还要把函数IsLegalDate再改回来
alter FUNCTION IsLegalDate
(@y int,@m int,@d int)
RETURNS bit
AS EXTERNAL NAME ZSqlExtend.[ZSqlExtend_NS.ZSqlExtend_cls].IsLegalDate;
go    
  这里需要注意2个问题:
  1、也许你会问,既然要把函数IsLegalDate改掉,让它和程序集ZSqlExtend无关,何不直接用语句:
  ALTER FUNCTION [dbo].[IsLegalDate]
  (@y [int], @m [int], @d [int])
RETURNS [bit]
begin
    return 1;
end

  哈哈,你会得到如下提示:  
  无法对 'dbo.IsLegalDate' 进行更改,因为它是不兼容的对象类型。  
  2、为什么要再编译个DLL呢?把编译好的ZSqlExtend.dll改个名那个“假的”不就有了吗。原来Sql Server在建程序集时把dll文件变成二进制流存入数据库,如果两个dll完全相同就是文件名不一样,那会收到如下提示:    CREATE ASSEMBLY 失败,因为根据 MVID,源程序集应与已按名称 "ZSqlExtend" 注册的程序集完全相同。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-81225-1-1.html 上篇帖子: SQL Server:移动系统数据库 下篇帖子: SQL点滴15—在SQL Server 2008中调用C#程序
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表