• MS SQL Server2000转换成MySQL


      按计划今天着手进行将后台数据库从MS SQL Server2000转换成MySQL5.1.3。目的是便于发布软件的测试版本。

      1. 驱动: mysql-connector-odbc-5.1.11-win32.msi。测试Win7*64, XP通过, Win7*32、Win8的暂时没环境测试,待测

      2. MySQL_5.1.3免安装版。

      3. MSS2SQL工具软件转换SQLServer2000的表结构。一共转换了43个表。

      4. MSSQLServer2000到MySQL的存储过程的转换

      (1)同表复制数据

      #接触MySQL没几天,写的语句自己也觉得有些啰嗦,肯定可以优化,只能深入学习之后再进行了。 

       # To-Do.  2015年5月18日 10:14:51

      DROP PROCEDURE IF EXISTS SP_UpdateData;
       DELIMITER //
       CREATE PROCEDURE SP_UpdateData (OLID VARCHAR(38), NLID VARCHAR(38), TableName VARCHAR(38))
       BEGIN
         SET @tablename=TableName;
         SET @tmptablename=CONCAT(@tablename,'_tmp');

         #删除临时表, 不加这句下次执行时会报错,提示临时表已存在

         SET @sqlcmd=CONCAT('DROP TEMPORARY TABLE IF EXISTS ', @tmptablename); 
         PREPARE stmt FROM @sqlcmd;
         EXECUTE stmt;
         DEALLOCATE PREPARE stmt;
         

         #创建临时表
         SET @sqlcmd=CONCAT('CREATE TEMPORARY TABLE ', @tmptablename);
         SET @sqlcmd=CONCAT(@sqlcmd, ' SELECT * FROM ');
         SET @sqlcmd=CONCAT(CONCAT(@sqlcmd, @tablename), ' WHERE 1=0');
         PREPARE stmt FROM @sqlcmd;
         EXECUTE stmt;
         DEALLOCATE PREPARE stmt;
        

         #将来源数据插入临时表
         SET @sqlcmd=CONCAT('INSERT INTO ', @tmptablename);
         SET @sqlcmd=CONCAT(@sqlcmd, ' SELECT * FROM ');
         SET @sqlcmd=CONCAT(@sqlcmd, @tablename);
         SET @sqlcmd=CONCAT(@sqlcmd, ' WHERE LID=?');
         SET @a=OLID;
         PREPARE stmt FROM @sqlcmd;
         EXECUTE stmt USING @a;
             DEALLOCATE PREPARE stmt;

        #刷新临时表的外键为NLID

         SET @sqlcmd=CONCAT(CONCAT('UPDATE ', @tmptablename), ' SET MID=UUID(), LID=?');
         SET @b=NLID;
             PREPARE stmt FROM @sqlcmd;
         EXECUTE stmt USING @b;
         DEALLOCATE PREPARE stmt;

         #临时表中数据插入回原表

         SET @sqlcmd=CONCAT(CONCAT(CONCAT('INSERT INTO ', @tablename), ' SELECT * FROM '), @tmptablename);
         PREPARE stmt FROM @sqlcmd;
         EXECUTE stmt;
         DEALLOCATE PREPARE stmt;
      END //
      DELIMITER ;

      (2)查询树形结构子节点

       #遍历父节点ParentMID下的所有树节点, 开始时想参考SQL Server中的写法,利用临时表, 但是测试时报错,原因见8

          #因为对MySQL不熟悉,干脆直接新建了表,当临时表用, 实现功能先。

      DROP PROCEDURE IF EXISTS SP_GetChildrenNodes;
      DELIMITER //
      CREATE PROCEDURE SP_GetChildrenNodes (ParentMID VARCHAR(50), Maker VARCHAR(20), IncludeRoot INT) 
      BEGIN
        DELETE FROM A_tmp WHERE cMaker=Maker;
        INSERT INTO A_Tmp (MID,cMaker) SELECT ParentMID, Maker;
        WHILE EXISTS (SELECT MID FROM A WHERE PreMID IN (SELECT MID FROM A_tmp WHERE cMaker=Maker) AND MID NOT IN (SELECT MID FROM A_tmp WHERE cMaker=Maker)) DO
          INSERT INTO A_tmp (MID,cMaker) SELECT MID,Maker FROM A WHERE PreMID IN (SELECT MID FROM A_tmp WHERE cMaker=Maker) AND MID NOT IN (SELECT MID FROM A_tmp WHERE cMaker=Maker);
        END WHILE;
        IF IncludeRoot = 1 THEN #查询结果包含父节点
          SELECT * FROM A WHERE MID IN (SELECT MID FROM A_tmp WHERE cMaker=Maker) ORDER BY PreMID,iSerialNO;
        ELSE
          SELECT * FROM A WHERE MID IN (SELECT MID FROM A_tmp WHERE MID<>ParentMID AND cMaker=Maker) ORDER BY PreMID,iSerialNo;
        END IF;
      END; //
      DELIMITER ;

      5. SQL函数的区别

      (1) select *   from A where convert(nvarchar(10),tMakeDate,121)>='2015-05-08'

      ->SELECT * from A WHERE DATE_FORMAT(tMakeDate, '%Y-%m-%d')>='2015-05-08'

      (2) select * from A where isnull(cMaker, '')<>''

      -> SELECT * from A where IFNULL(cAuditMan,'')<>''

      (3) select newid()

      ->SELECT UUID()

        select getdate()

      ->SELECT NOW()

      (4) update a set a.字段1=b.字段2 from 表A  a, 表B  b where a.MID='1'

      ->UPDATE 表A  a, 表B  b SET a.字段1=b.字段2 WHERE a.MID='1' AND b.MID='2'

      (5) select top 10 * from A

      -> SELECT * FROM A LIMIT 10

      (6) select convert(nvarchar(10),getdate(),121) as Date1, convert(nvarchar(10),getdate()-2,121) as Date2

      ->SELECT DATE_FORMAT(NOW(),'%Y-%m-%d') as Date1, DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 2 DAY), '%Y-%m-%d') as Date2

      (7) insert into A(MID,iType) select newid(), 1 where not exists(select 1 from A where iType=1)

      ->INSERT INTO A(MID, iType) SELECT UUID(), 1 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM A WHERE iType=1)  #Dual虚拟表

      (8)where (4&IFNULL(iUserRight,0))=4

      ->WHERE(4&&IFNULL(iUserRight,0))=1

      (9)添加字段 并指定编码格式

      alter table A add cNewFldName varchar(20) CHARACTER SET utf8 DEFAULT null;

      6. 设置MYSQL为UTF8编码

      修改my.ini配置文件,参考:http://blog.csdn.net/red4711/article/details/6007248

      

      (1)在 [mysqld]块中加上以下内容:

      default-character-set = utf8

      character_set_server = utf8

      注意:如果此标签下已经存在“default-character-set=GBK”类似的内容,只需修改即可。

      (2)在 [mysql]块中加上一行

      default-character-set = utf8 

      (3)在 [mysql.server]块中加上一行

      default-character-set = utf8 

      (4)在 [mysqld_safe]块中加上一行

      default-character-set = utf8 

      (5)在 [client]块中加上一行

      default-character-set = utf8

      (6)重启MySql服务

      修改My.ini后,重启MySQL服务,上截图中的latin1会调整为utf8, 如下图所示:

      

      7. MYSQL中不支持匿名块,也就是说过程性语句IF,THEN必须放在存储过程中执行。

      MS SQL Server中类似先判断 if exists (select 1 from A where MID='1')  再执行其它操作的语句在MySQL中要作调整。

      8. MySQL中不允许在同一语句中对临时表多次引用

      9. 存储过程中利用 exec 执行动态语句

      SQL Server中能方便的将表名、字段名、(查询)条件等组合成SQL语句,利用exec、sp_executesql 执行动态语句,MySQL中区别不小:

      MSSQLServer: //同一表中复制新增数据 

        set @mysql='select * into #temp from '+ @TableName+' where 1=0'
          set @mysql=@mysql+' insert into #temp select * from '+@TableName+' where LID='''+@OLID+''''
          set @mysql=@mysql+' update #temp set MID=newid() ,LID='''+@NLID+''''
          set @mysql=@mysql+' insert into '+ @TableName+' select * from #temp '
          exec(@mysql)

       MySQL: 

      参考:http://blog.csdn.net/moshuchao/article/details/2153342

      从MySQL 5.0 开始,支持了一个全新的SQL句法:
      PREPARE stmt_name FROM preparable_stmt;
      EXECUTE stmt_name [USING @var_name [, @var_name] ...];
      {DEALLOCATE | DROP} PREPARE stmt_name;

      (1)将表名作参数

      

      测试时本想用下述思路:

      a: SET @sqlcmd='select * from ?';

       b: SET @tablename='test';

       c: PREPARE stmt FROM @sqlcmd;

       d: EXECUTE stmt USING @tablename;

       e: DEALLOCATE PREPARE stmt;

      在命令行中执行到c时,报错:

      ERROR 1064(42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1

      (2)将表名、查询字段、查询字段值 作为参数

      

      实际存储过程见4.(1)同表复制数据

       10. MYSQL无法对字段设置类似MSSQLServer中newid()默认值。

      代码中涉及操作数据库的地方已基本改完,接下来就要考虑数据库升级、备份、还原、数据文件安全等问题了,牵一发动全身,改点东西真是不容易……

      2015年7月8日 09:48:33

      11. 昨晚改了几个日期字段的类型timestamp改成datetime, 当时没注意,把允许空的选项给去掉了,今早来运行程序,报错,提示: 

      数据提供程序或其他服务返回 E_FAIL 状态。

      重新将字段设置为允许空,问题解决。

  • 相关阅读:
    LightOJ 1341 Aladdin and the Flying Carpet 数学
    NOIP2013 花匠 DP 线段树优化
    LightOJ 1370 Bi-shoe and Phi-shoe 欧拉函数+线段树
    BZOJ2818: Gcd 欧拉函数求前缀和
    SPOJ3267 D-query 离线+树状数组 在线主席树
    BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
    拓展欧几里得算法
    POJ1845Sumdiv(求所有因子和 + 唯一分解定理)
    UVA1635 Irrelevant Elements(唯一分解定理 + 组合数递推)
    codeforce 626E(二分)
  • 原文地址:https://www.cnblogs.com/mozzie/p/4506201.html
Copyright © 2020-2023  润新知