免费试用

SQL Server 存储过程迁移到 OceanBase 的实战案例

目录

一、迁移背景

随着 OceanBase 在金融核心交易、政务系统、大型互联网平台等关键领域的广泛应用,大量使用 SQL Server 的企业面临向国产化、高性能 OceanBase 迁移的迫切需求。在迁移过程中,存储过程的兼容性和业务逻辑完整性成为关键瓶颈。
本次实战案例中,企业的某业务系统大量依赖 SQL Server 存储过程完成批量数据初始化和统计分析,迁移至 OceanBase MySQL 时需要解决事务控制、变量声明、日期函数、字符串拼接和异常处理等不兼容问题。为了确保迁移高效、准确,同时减少手工改写成本,我们使用 SQLShift 工具进行自动化转换。

二、SQLShift的转换能力

SQLShift 是一个面向异构数据库迁移的智能工具,自动识别 SQL Server 的 T-SQL 语法特性,并映射为OB等效语法,以下为待迁移的 SQL Server 存储过程:

点击查看原始 SQL Server 存储过程代码
CREATE PROCEDURE [dbo].[RT_Tang_YW_MainC_InitAwb60Finish]
 AS
 -- 声明变量
DECLARE @Period60 int  
DECLARE @Period180 int 

DECLARE @Yw_Op_Date datetime 
DECLARE @Yw_Start_Time datetime 
DECLARE @tran_error int

declare @AwbYwDate60 datetime
declare @AwbYwDate180 datetime

--变量赋值
SET @Period60 =-60
SET @Period180 =-180
SET @Yw_Start_Time = Getdate()
SET @tran_error = 0



SELECT @Yw_Op_Date = Max(Yw_Op_Date) FROM Tbl_Yw_Log WHERE OPTRESULT='RUN'
	IF @Yw_Op_Date IS Null
	BEGIN 
		SELECT @Yw_Op_Date=Getdate()
	END 

Set @AwbYwDate60 =DateAdd(day,@Period60,@Yw_Op_Date)
Set @AwbYwDate180 =DateAdd(day,@Period180,@Yw_Op_Date)


--定义隔离级别为最低
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


--Tbl_Awb_Basic_Temp
BEGIN TRAN
SET @tran_error = 0
BEGIN TRY

	
	delete  from  Cargo2YWTemp..Tbl_Awb_Basic_Temp
	where  AwbPrefix+RTrim(AwbNo)+AwbPostfix 
	in(Select AwbPrefix+RTrim(AwbNo)+AwbPostfix as TmpFinishFlag 
		FROM Tbl_Cargo 
		WHERE AwbPrefix+RTrim(AwbNo)+AwbPostfix 
			In (Select AwbPrefix+RTrim(AwbNo)+AwbPostfix From Tbl_Awb_Basic Where (Op_Date < CONVERT(CHAR(10),@AwbYwDate60,121) And Op_Date > CONVERT(CHAR(10),@AwbYwDate180,121)) ) 
			And FinishFlag !=0 --Finished
			And Flight_Dep=Flight_Dest
		GROUP BY AwbPrefix,AwbNo,AwbPostfix
	) 

	Insert Into Cargo2YWTemp..Tbl_Awb_Basic_Temp(AwbPrefix,AwbNo,AwbPostfix,YwTreate)
	Select distinct AwbPrefix,AwbNo,AwbPostfix,1 
	From 
	( 
		Select AwbPrefix,AwbNo,AwbPostfix,Min(FinishFlag) as TmpFinishFlag 
		FROM Tbl_Cargo 
		WHERE AwbPrefix+RTrim(AwbNo)+AwbPostfix 
			In (Select AwbPrefix+RTrim(AwbNo)+AwbPostfix From Tbl_Awb_Basic Where (Op_Date < CONVERT(CHAR(10),@AwbYwDate60,121) And Op_Date > CONVERT(CHAR(10),@AwbYwDate180,121)) ) 
			And FinishFlag !=0 --Finished
			And Flight_Dep=Flight_Dest
		GROUP BY AwbPrefix,AwbNo,AwbPostfix
	) Tbl_Temp 
	Where TmpFinishFlag>0


	SET @tran_error = @tran_error + @@error
END TRY
   BEGIN CATCH       
      --执行出错,回滚事务
       ROLLBACK TRAN
	  
       SET @tran_error = @tran_error + 1;
	   -- 记录异常
	   INSERT INTO TBL_SP_ErrLog(ErrTable,ErrDate) VALUES('Tbl_Awb_Basic_Temp',getdate())
	   RAISERROR ( N'Tbl_Awb_Basic_Temp 出现异常', 17,1 ); 
    END CATCH
IF(@tran_error = 0)
    --没有异常,提交事务
    COMMIT TRAN 


BEGIN TRAN
SET @tran_error = 0
BEGIN TRY
	UPDATE Cargo2YWTemp..Tbl_Awb_Basic_Temp 
	SET AwbDate=a.Op_Date,AwbDest=substring(a.routing,len(a.routing)-2,3),Piece=a.Piece 
	FROM Cargo2YWTemp..Tbl_Awb_Basic_Temp t ,Tbl_Awb_Basic a 
	WHERE a.AwbNo=t.AwbNo 
		AND a.AwbPrefix=t.AwbPrefix 
		AND  a.AwbPostfix=t.AwbPostfix 

	SET @tran_error = @tran_error + @@error
END TRY
   BEGIN CATCH       
      --执行出错,回滚事务
       ROLLBACK TRAN
	  
       SET @tran_error = @tran_error + 1;
	   -- 记录异常
	   INSERT INTO TBL_SP_ErrLog(ErrTable,ErrDate) VALUES('Tbl_Awb_Basic_Temp',getdate())
	   RAISERROR ( N'Tbl_Awb_Basic_Temp 出现异常', 17,1 ); 
    END CATCH
IF(@tran_error = 0)
    --没有异常,提交事务
    COMMIT TRAN 

--Tbl_Awb_Basic_Temp
BEGIN TRAN
SET @tran_error = 0
BEGIN TRY

	--
	UPDATE Cargo2YWTemp..Tbl_Awb_Basic_Temp	
	SET YwTreate=0 
	FROM Cargo2YWTemp..Tbl_Awb_Basic_Temp bt ,(SELECT SUM(Piece) AS Piece,AwbPrefix,AwbNo,AwbPostfix
	    FROM (SELECT c.Piece,c.AwbPrefix,c.AwbNo,c.AwbPostfix
			FROM Cargo2YWTemp..Tbl_Awb_Basic_Temp t 
			JOIN Tbl_Cargo c 
			ON c.Flight_Dep=t.AwbDest And c.Flight_Dest=t.AwbDest AND c.AwbNo=t.AwbNo AND c.AwbPrefix=t.AwbPrefix AND c.AwbPostfix=t.AwbPostfix 
			) b
		GROUP BY  AwbPrefix,AwbNo,AwbPostfix) a
	WHERE a.AwbNo=bt.AwbNo AND a.AwbPrefix=bt.AwbPrefix AND  a.AwbPostfix=bt.AwbPostfix AND bt.Piece=a.Piece


	SET @tran_error = @tran_error + @@error
END TRY
   BEGIN CATCH       
   --执行出错,回滚事务
       ROLLBACK TRAN
	  
       SET @tran_error = @tran_error + 1;
	   -- 记录异常
	   INSERT INTO TBL_SP_ErrLog(ErrTable,ErrDate) VALUES('Tbl_Awb_Basic_Temp',getdate())
	   RAISERROR ( N'Tbl_Awb_Basic_Temp 出现异常', 17,1 ); 
    END CATCH
IF(@tran_error = 0)
    --没有异常,提交事务
    COMMIT TRAN

--Tbl_Cargo_ChargeCorrection_Temp
BEGIN TRAN
SET @tran_error = 0
BEGIN TRY

	delete  from  Cargo2YWTemp..Tbl_Cargo_ChargeCorrection_Temp where CCANo in(Select distinct AwbNo From Tbl_Awb_Basic_Temp) 


	INSERT INTO Cargo2YWTemp..Tbl_Cargo_ChargeCorrection_Temp (CCAPrefix,CCANo,CCAPostfix)
	SELECT DISTINCT CCAPrefix,CCANo,CCAPostfix 
	FROM Tbl_Cargo_ChargeCorrectionDetail a
    JOIN Cargo2YWTemp..Tbl_Awb_Basic_Temp t
	ON a.AwbPrefix = t.AwbPrefix AND a.AwbNo = t.AwbNo AND a.AwbPostfix = t.AwbPostfix 


	SET @tran_error = @tran_error + @@error
END TRY
   BEGIN CATCH       
      --执行出错,回滚事务
       ROLLBACK TRAN
	  
       SET @tran_error = @tran_error + 1;
	   -- 记录异常
	   INSERT INTO TBL_SP_ErrLog(ErrTable,ErrDate) VALUES('Tbl_Cargo_ChargeCorrection_Temp',getdate())
	   RAISERROR ( N'Tbl_Cargo_ChargeCorrection_Temp 出现异常', 17,1 ); 
    END CATCH
IF(@tran_error = 0)
    --没有异常,提交事务
    COMMIT TRAN

SQLShift自动识别并转换这些不兼容的语法点

在迁移过程中,SQL Server 存储过程中的以下语法与 OceanBase MySQL 不兼容,SQLShift将智能识别并转换:

类型SQL Server 写法OceanBase MySQL 替代方案
存储过程声明CREATE PROCEDURE [dbo].[ProcName]CREATE PROCEDURE ProcName()
变量声明DECLARE @var INTDECLARE var INT; (去掉 @)
变量与列名冲突@Yw_Op_Date改名为 Yw_Op_Date_local
日期函数GETDATE()NOW()
日期计算DATEADD(day, x, y)DATE_ADD(y, INTERVAL x DAY)
日期格式转换CONVERT(CHAR(10), date, 121)DATE_FORMAT(date, '%Y-%m-%d')
字符串拼接AwbPrefix+RTRIM(AwbNo)+AwbPostfixCONCAT(AwbPrefix, RTRIM(AwbNo), AwbPostfix)
字符串截取SUBSTRING(str, start, LEN(str)-2)SUBSTRING(str, start, LENGTH(str)-2)
双层表名Cargo2YWTemp..Tbl_XCargo2YWTemp.Tbl_X
事务控制BEGIN TRAN / COMMIT / ROLLBACKSTART TRANSACTION / COMMIT / ROLLBACK
异常处理TRY...CATCHDECLARE EXIT HANDLER FOR SQLEXCEPTION + 内部执行 ROLLBACK、插入日志和 SIGNAL
UPDATE 语法UPDATE t SET ... FROM t JOIN a ...UPDATE t JOIN a ON ... SET ...

三、SQLShift转换后在目标端成功执行

在 OceanBase MySQL 上执行转换后的存储过程,验证结果如下:

  • 事务均能正常提交或回滚;
  • DELETE、INSERT、UPDATE 操作正确执行,运单初始化逻辑保持一致;
  • 日期计算、字符串拼接结果与 SQL Server 保持一致;
  • 异常日志成功写入 TBL_SP_ErrLog 表;
  • 整个过程无需修改业务逻辑,迁移一次成功。 执行截图

四、总结:从繁琐手工迁移到智能转换

无论您是航空物流企业对核心运单处理系统进行数据库升级,还是大型企业将 SQL Server 存储过程迁移至 OceanBase 以统一数据库平台,SQLShift 都是快速、平稳落地 OceanBase 的关键加速器。它能够自动处理变量、日期、字符串、事务与异常等不兼容语法,显著节省手工改写、调试与验证成本,确保业务逻辑一致性,实现迁移效率与可靠性的双重提升。

现在开始免费试用SQLShift

打破异构数据库限制,智能实现存储过程等非表对象无缝适配,免去您高额改造成本!

免费试用