嗨,大家好,
去年,我有机会与R&D团队合作,该团队致力于DB脚本转换。
尽管有可用的迁移工具,但它仅转换表和约束。
其余的东西(存储过程,函数)..我们必须手动进行编辑。
那个时候,我们面临着一些有趣的挑战。.我没有记录所有这些挑战,但是我可以和你分享的任何东西..我会尽力.. :)
==================================================
指数
-------------------------------------------------- -----
1. MySQL变量
-用户变量(全局变量)
-局部变量
2.迁移提示
如何获得
-最后插入的身份值
-当前日期和时间
-声明一个哑表
3. MySQL字符串函数
-CONCAT
-CONCAT_WS
-GROUP_CONCAT
4.唯一身份
5.如何有条件地从SP返回(退出)?
6.如何在存储过程中执行Dynamic SQL?
7. MySQL游标
==================================================
1. MySQL变量在MySQL中,有两种类型的变量:
用户变量:(全局变量)-符号“ @”用于指定它们。
-用户变量是一个变量,在与数据库的整个连接过程中都有效。
-给定客户端连接的所有变量都会在该客户端退出时自动释放。
-用户定义的变量是特定于连接的。 也就是说,一个客户端定义的用户变量不能被其他客户端看到或使用。
-在MySQL 5.0及更高版本中,用户变量名称不区分大小写。
-语法:SET @var_name = expr [,@var_name = expr]…
-示例:SET @ t1 = 0,@ t2 = 0,@ t3 = 0;
-注意:您也可以在SET以外的语句中为用户变量分配值。
在这种情况下,赋值运算符必须为:=而不是=,因为=在非SET语句中被视为比较运算符
例如
SET @t1=1, @t2=2, @t3=3;
SELECT @t1,@t2,@t3; ==> output: 1,2,3
SELECT @t1:=8,@t2,@t3; ==> output: 8,2,3
局部变量:(在存储过程中推荐)
-DECLARE语句用于声明局部变量。
-局部变量仅在过程主体中起作用。
-DECLARE只能在BEGIN…END复合语句中使用,并且必须在其开始处以及其他任何语句之前。
-变量的范围在BEGIN…END块内。
-语法:DECLARE var_name [,var_name]…输入[DEFAULT值]
-示例:DECLARE l_TagID INT默认值0;
-注意:如果缺少DEFAULT子句,则初始值为NULL。
如何在MySQL中使用局部变量:
————————————
要将Microsoft SQL Sever本地变量名称(@var)更改为MySQL本地变量名称,请将符号“ @”替换为“ v_”。 (全选,全部替换)
示例:@userID ==> v_userID
————————————
MS-SQL:
DECLARE @uname, @addr VARCHAR(200);
SELECT @uname = uname, @addr = address FROM tbluser WHERE uid = @uid;
MySQL:
DECLARE v_uname, v_addr VARCHAR(200);
SELECT uname, address INTO v_uname, v_addr tbluser FROM tbluser WHERE uid = v_uid;
————————————
例:
DELIMITER $$
DROP PROCEDURE IF EXISTS `mytest`$$
CREATE PROCEDURE `mytest`
(
IN v_id INT
)
BEGIN
create temporary table temp
(
id int primary key auto_increment ,
val int
);
insert into temp (val) values (22);
insert into temp (val) values (50);
insert into temp (id, val) values (99, 80);
insert into temp (val) values (9000);
begin
declare v_val int default 0;
select id, val into v_id, v_val from temp where id=v_id;
select v_id, v_val;
end;
– select v_id, v_val;
– (If you try to display local variables outof their scope (begin.. end), you will get error: Unknown column ‘v_val’ in ‘field list’)
drop temporary table temp;
END$$
DELIMITER ;
try to run it with: call mytest(100)
==================================================
2.迁移提示@@ IDENTITY在MySQL中也可用。
选择@@ IDENTITY作为'Identity';
它返回最后插入的标识值。
但是,最好使用LAST_INSERT_ID()
——————————————
如何从其他更新表
UPDATE JOIN …..
ON . = .
SET . =
WHERE
——————————————
MS-SQL:GetDate()==>使用sysdate(),SELECT CURRENT_TIMESTAMP;
——————————————
在没有引用表的情况下,可以将DUAL指定为虚拟表名
SELECT 1 FROM dual
WHERE left(@sSQL,2) in ('v_','d_','e_','f_','g_','h_','i_','j_')
==================================================
3. MySQL字符串函数
CONCAT功能:
————————
-始终使用CONCAT进行串联(以替换MS-SQL中的“ +”运算符)。
-避免使用“ ||” (双管)
-使用IFNULL(column_name,”)处理NULL值; 串联之前,否则将返回null。
例:
DELIMITER $$
DROP PROCEDURE IF EXISTS `mytest`$$
CREATE PROCEDURE `mytest`()
BEGIN
declare v_str1, v_str2, v_str3, v_str4 varchar(20);
declare v_res varchar(100);
set v_str1 = “abc”;
set v_str2 = “pqr”;
set v_str3 = “xyz”;
set v_str4 = “123″;
set v_res = concat(v_str1,v_str2,v_str3, v_str4); — , null);
select v_res;
END$$
DELIMITER ;
RUN: call mytest();
CONCAT_WS函数:
————————————
-用于用分隔符连接,是CONCAT()的一种特殊形式。
第一个参数是其余参数的分隔符。
将分隔符添加到要连接的字符串之间
-优于CONCAT:无需检查每列的IFNULL值。
它在内部照顾它。
-注意:如果分隔符为NULL,则结果为NULL。
语法:CONCAT_WS(separator,str1,str2,...);
例:
SELECT CONCAT_WS(’,’,’First name’,’Second name’,null,’Last Name’);
-> ‘First name,Second name,Last Name’
GROUP_CONCAT函数:
————————————————
-此函数返回一个字符串结果,该字符串结果具有来自组的串联的非NULL值。
-使用:将多个MySQL行连接到一个字段中
例:
————-
if
select col_name from temp_table;
==>
col_name
———-
‘abc’
‘xyz’
‘pqr’
declare v_str varchar(100);
select group_concat( col_name separator ‘*’) into v_str from temp_table;
select v_str;
output: ‘abc*xyz*pqr’
为什么要避免“ ||”
串联双管
——————————————————
可以使用双管道进行连接,但是,仅当sql模式为ansi时才合法。
您可以使用–ansi启动选项告诉mysqld以ANSI模式运行。
mysqld –事务隔离= SERIALIZABLE –sql模式= ANSI
要么,
设置可全局化的全球交易隔离级别;
SET GLOBAL sql_mode ='ANSI';
==================================================
4.如何更换UNIQUEIDENTIFIER在MySQL中,UNIQUEIDENTIFIER不是数据类型。
我们可以使用VARCHAR(50),因为两者都可以生成GUID。
MS-SQL:
——————-
NEWID()
输出:D747AE09-5E4C-44BB-BCAE-DD40EDD7747B
MySQL的:
——————-
UUID()
输出:28c93603-0752-102c-ab9e-93e0a9ae6d17
例:
————————————
DELIMITER $$
DROP PROCEDURE IF EXISTS `mytest`$$
CREATE PROCEDURE `mytest`()
BEGIN
DECLARE id VARCHAR(50);
SET id = UUID();
SELECT id;
END$$
DELIMITER ;
run it with: call mytest()
=============================================== 5 。如何有条件地从SP返回(退出)?
——————————————————
MS-SQL的SP中没有“ return”的替代关键字。
请改用“ LEAVE”。
在标签上加上多余的BEGIN&END(例如main)
它也用于通过循环退出。
例:
DELIMITER $$
DROP PROCEDURE IF EXISTS `mytest`$$
CREATE PROCEDURE `mytest`()
BEGIN
MAIN: BEGIN
SELECT ‘HI’;
IF 1=1 THEN
SELECT ‘ABC’;
LEAVE MAIN;
END IF;
SELECT ‘BYE’;
END MAIN;
END$$
DELIMITER ;
To Run: call mytest()
================================================ 6 。如何在存储过程中执行动态SQL
步骤1.连接它。
———————————————————
连接sql字符串并将其存储到用户变量中
SET @dynamic_sql = CONCATE(“ SELECT * FROM mytable”,“ WHERE userid =”,v_uid);
第2步。准备它。
———————————————————
要执行动态sql,您需要先准备它。
从@dynamic_sql中准备complete_sql;
注意:PREPARE语句不适用于局部变量(例如v_sql)。
它被明确设计为仅与用户变量和常量字符串一起使用。
步骤3.执行它。
———————————————————
执行complete_sql;
步骤4.取消分配它。
———————————————————
取消准备的语句。
取消预备complete_sql;
==================================================
7. MySQL游标游标具有以下主要步骤:
1)声明游标名称CURSOR FOR SELECT;
2)打开游标名称;
3)获取游标名称INTO变量[,variable];
4)关闭光标名称;
—————————————————————
例:
DELIMITER $$
DROP PROCEDURE IF EXISTS `newTest`$$
CREATE PROCEDURE `newTest`()
BEGIN
create temporary table temp
(
id int primary key auto_increment ,
val int
);
insert into temp (val) values (60);
insert into temp (val) values (60);
insert into temp (id, val) values (99, 80);
insert into temp (val) values (9000);
BEGIN
DECLARE colID, colVAL, handle INT;
DECLARE mycur CURSOR FOR SELECT id, val FROM temp; -- declare cursor
DECLARE CONTINUE HANDLER FOR NOT FOUND SET handle = 1; -- declare handle
OPEN mycur; -- open cursor
FETCH mycur INTO colID, colVAL; -- fetch first row values from cursor
REPEAT
SELECT colID, colVAL; -- your code
FETCH mycur INTO colID, colVAL; -- fetch values from cursor
UNTIL handle = 1
END REPEAT;
CLOSE mycur; -- close cursor
END;
drop temporary table temp;
END$$
DELIMITER ;
call newTest();
From: https://bytes.com/topic/mysql/insights/875360-mysql-ms-sql-conversion