• SQL Server 2012 已经发布,维护如此多版本的SQL Server需要合适的工具和技巧


    2012年第二季度,SQL Server 2012就已经发布。作为普通的开发者,并没有太多的热情去追随这些潮流的技术,经过短暂的尝鲜,果断决定放在一边,不予以理会。从SQL Server 2000起,就一直把SQL Server作为首选的项目数据库平台。随着SQL Server 2005, 2008, 2008 R2, 2012等系列版本的陆续发布,面临的问题也越来越多。遇到最多的一个问题是,SQL Server不同版本间的数据库转化问题。

    举例说明,在几百个客户中,至今仍然有使用SQL Server 2000的,以我的经验,这个版本的SQL Server还有相当多的客户在用。2006年之后的客户,从开始上项目就推荐用SQL Server 2005,所以沿袭过来,他们一直是这个版本的。到了2009年,新的客户又被推荐使用SQL Server 2008或是SQL Server 2008 R2,从理解上来说,SQL Server 2008 R2相当于SQL Server 2010。再加上这几个版本之间有补丁包,SQL Server的版本又增加了好几个,理论上推荐客户升级到最新的补丁包,也有客户因稳定性的原因,拒绝升级。于是乎,就为一个SQL Server,就有好多个版本。作为开发者,一般只有装最新的SQL Server,以便于防止在查找客户问题时,发生数据库版本不兼容,无法还原数据库的错误。然而,最新的SQL Server 2012,不再支持SQL Server 2000的备份文件,这不是个好消息。

    对于下面的这个错误,在客户比较多的情况下,经常会遇到。比如要拿客户的数据库回来查找问题,这个问题经常出现。如果耐心不好,就干脆装个最新的SQL Server,如果不想这样,下面提供的几种方法,也许对你有所帮助。

    image

    SQL Server Import/Export

    SQL Server自带的导入导出向导,大部分情况下有效。我推荐的步骤是先创建目标数据库的脚本,让SQL Server只传输数据,而不是既创建表,又传输数据,以减少一些很奇怪的错误。

    image

    这个工具用的不多,有各种奇怪的问题,没有积累多的经验。

    SQL Object Level Recovery Native

    RedGate公司SQL Toolbet系列组件的一个,可以从SQL Server的备份文件中生成带数据的SQL语句,在目标数据库中直接执行即可。这种方法的成功率很高,简单的带数据的SQL INSERT语句,在任何版本的SQL Server中,都可以很正确的插入数据。

    image

    点击View Recovery Script,可以查看它生成的SQL 脚本,直接把备份数据文件转化为SQL语句,相当方便。

    目前支持SQL Server 2008 R2的备份集,可以满足绝大部分客户的应用。

    SQL Query  Generator

    公司的工具库里面的一个工具,一般是给客户维护(support)人员用,用于快速导入导出数据。

    image

    以Northwind数据库为例子,可以马上生成这个表的INSERT语句,保存到剪贴板中,例子语句如下所示

    INSERT INTO [Employees] ([EmployeeID],[LastName],[FirstName],[Title],[TitleOfCourtesy],[BirthDate],[HireDate],[Address],[City],[Region],[PostalCode],[Country],[HomePhone],[Extension],[Photo],[Notes],[ReportsTo],[PhotoPath])
    VALUES(9, N'Dodsworth', N'Anne', N'Sales Representative', N'Ms.', '1966-1-27 0:0:0.0', '1994-11-15 0:0:0.0', N'7 Houndstooth Rd.', N'London', N'', N'WG2 7LT', N'UK', N'(71) 555-4444', N'452', N'System.Byte[]', N'Anne has a BA degree in English from St. Lawrence College.  She is fluent in French and German.', 5, N'http://accweb/emmployees/davolio.bmp')
    
    INSERT INTO [Employees] ([EmployeeID],[LastName],[FirstName],[Title],[TitleOfCourtesy],[BirthDate],[HireDate],[Address],[City],[Region],[PostalCode],[Country],[HomePhone],[Extension],[Photo],[Notes],[ReportsTo],[PhotoPath])
    VALUES(8, N'Callahan', N'Laura', N'Inside Sales Coordinator', N'Ms.', '1958-1-9 0:0:0.0', '1994-3-5 0:0:0.0', N'4726 - 11th Ave. N.E.', N'Seattle', N'WA', N'98105', N'USA', N'(206) 555-1189', N'2344', N'System.Byte[]', N'Laura received a BA in psychology from the University of Washington.  She has also completed a course in business French.  She reads and writes French.', 2, N'http://accweb/emmployees/davolio.bmp')

    这样,很方便的搬动数据库到另一个位置,简单灵活。对于图片数据,要单独处理。对于有种子字段的列,要在导入前,开启,语句如下所示

    SET IDENTITY_INSERT dbo.ICMOVh OFF 
    SET IDENTITY_INSERT dbo.ICMOVD ON

    对于主从表数据,先导入主表,再导入从表。删除主从表数据,则是先删从表,再删主表。

    LLBL Gen

    作为ORM的基本特征,跨数据库平台。你可以运用此特点,从一个数据库中读取,然后改变连接字符串,在另一个数据库中保存,完成数据库的转移工作。以销售单为例子,读取销售单的代码,看起来是这样的

    public SalesOrderEntity GetSalesOrder(System.String RefNo, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList fieldList)
    {
                SalesOrderEntity _SalesOrder = new SalesOrderEntity(RefNo);
                using (DataAccessAdapterBase adapter = GetCompanyDataAccessAdapter())
                {
                    bool found = adapter.FetchEntity(_SalesOrder, prefetchPath, null, fieldList);
                    if (!found) throw new Foundation.Common.RecordNotFoundException("Invalid SalesOrder");
                }
                return _SalesOrder;
    }

    同时,保存销售单的代码,看起来是这样的

    public SalesOrderEntity SaveSalesOrder(SalesOrderEntity SalesOrder, EntityCollection entitiesToDelete, string seriesCode)
     {
                using (DataAccessAdapterBase adapter = GetCompanyDataAccessAdapter())
                {
                    try
                    {
                        adapter.StartTransaction(IsolationLevel.ReadCommitted, "SaveSalesOrder");
                        adapter.SaveEntity(SalesOrder, true, false);
                        adapter.Commit();
                    }
                    catch
                    {
                        adapter.Rollback();
                        throw;
                    }
                }
                return SalesOrder;
    }

    这些代码均是由代码生成器直接生成的。完成数据转移的ORM代码,看起来是这样子的

    string source = "Data Source=192.168.0.96;Initial Catalog=TS;User Id =sa ; Password =holiday;";
    string destination = "Data Source=192.168.0.200;Initial Catalog=TS;User Id = sa ; Password = holiday;";
    ClientProxyFactory.ConnectionString = source;            
    ISalesOrderManager manager = ClientProxyFactory.CreateProxyInstance<ISalesOrderManager>();
    SalesOrderEntity salesOrder = manager.GetSalesOrder(customerNo, null);
    ClientProxyFactory.ConnectionString = destination;
    manager.SaveSalesOrder(salesOrder);

    就这样几句代码,把销售单数据从192.168.0.96的机器搬动到192.168..0.200的机器上。

    更进一步的,这几句代码可以写成一个泛型的方法,传入参数,即可达到批量搬动数据。

    以我的理解和摸索,当前仍然是让项目使用主流的SQL Server 2005,搭配Express版本的SQL Server 2008, 2008 R2,这样可以读取高于SQL Server 2005的客户数据库,兼容于更新的数据库。为了在不同的版本的SQL Server之间互导数据,供您参考。

  • 相关阅读:
    机器学习入门之二:一个故事说明什么是机器学习(转载)
    机器学习入门之一:背景介绍(转载)
    python 读取CSV文件 中文乱码
    如何快速学习一门新技术(转载)
    Oracle12c多租户如何启动关闭CDB或PDB (PDB自动启动)
    oracle单实例12.2.0.1安装
    PRVF-0002 : could not retrieve local node name
    图形化升级单机oracle 11.2.0.4 到 12.2.0.1
    ORA-00845: MEMORY_TARGET not supported on this system
    行转列、列转行
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/2705249.html
Copyright © 2020-2023  润新知