Oracle存储过程转成Sqlserver存储过程

本文介绍了Oracle存储过程迁移到Sqlserver存储过程中日期、ROWID及ROWNUM等关键元素的具体转换方法。通过实例对比,帮助读者理解不同数据库间的语法差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Oracle存储过程转成Sqlserver存储过程

 

1.日期转换

Oracle: TO_NUMBER(TO_CHAR(SYSDATE, 'YYYYMMDD'))

SqlServer:CAST(CONVERT(CHAR(8),GETDATE(), 112) AS INT)

    注:其中‘YYYYMMDD’格式   对应112

2.ROWID转换

Oracle: ROWID

SqlServer: PRIMARY KEY(表主键)

3.ROWNUM

Oracle: ROWNUM = 1

SqlServer: Top 1

  注:一般Select中的这个可以直接替换,但是在Update中就比较难了,如下:

       Oracle: UPDATE ITEM_MST SET
                       HISD_FLAG = 1

                   WHERE
                      ROWID = C2.ROWID;

       Sqlserver : UPDATE ITEM_MST SET
                             HISD_FLAG = 1        --AND ROWNUM = 1  ---KEY
                         WHERE ITEM_CD IN     --=

                             (SELECT TOP 1 ITEM_CD FROM ITEM_MST WHERE SALES_NO = @C1_ITEM_NAME )

 

      也就是说,可以利用该行中其他的已知信息获取该项数据。

 

 

 

。。。。。。

(未完,待续。)

 

<think>我们有一个Oracle存储过程,需要转换为SQL Server存储过程。以下将逐步分析并转换。 原始Oracle存储过程功能:根据传入的序列号(T_SN)和工站名称(T_STATIONNAME),获取该序列号的相关属性信息,包括工单、料号、工单线体、路由、工单颜色、K&NK等,以及根据配置的特定属性SQL语句获取其他属性。 转换步骤: 1. 语法差异: - Oracle的`VARCHAR2` -> SQL Server的`VARCHAR`/`NVARCHAR` - 变量声明位置:Oracle在`IS`之前,SQL Server在`AS`之后,并使用`DECLARE` - 异常处理:Oracle的`EXCEPTION` -> SQL Server的`TRY...CATCH` - 动态SQL:Oracle使用`EXECUTE IMMEDIATE`,SQL Server使用`EXEC`或`sp_executesql` - 输出参数:Oracle在参数列表中指定`OUT`,SQL Server同样,但调用时需用`OUTPUT`关键字 - 游标循环:Oracle的`FOR CURR_SQL IN (SELECT ...) LOOP` -> SQL Server使用游标或临时表 - 字符串连接:Oracle的`||` -> SQL Server的`+` - 函数替换:例如`INSTR` -> `CHARINDEX`,`SUBSTR` -> `SUBSTRING`,`DECODE` -> `CASE WHEN`等 - 行计数:Oracle的`SELECT COUNT(1) INTO V_COUNT` -> SQL Server的`SELECT @V_COUNT = COUNT(1) ...` 2. 具体转换: - 存储过程定义:将`CREATE OR REPLACE PROCEDURE`改为`CREATE PROCEDURE`或`ALTER PROCEDURE` - 去掉`IS`,改为`AS`,并在`BEGIN`之前声明变量 - 标签跳转:Oracle的`<<ENDP>>`和`GOTO ENDP`,在SQL Server中可以用`RETURN`或`GOTO`(但尽量少用),这里我们使用条件判断避免跳转 - 异常处理:将Oracle的异常块转换为SQL Server的`TRY...CATCH` - 动态SQL:将Oracle的`EXECUTE IMMEDIATE`转换为SQL Server的`EXEC`或`sp_executesql`,注意SQL Server中动态SQL不能直接返回标量值,需要将结果赋值给变量,这里我们可以用`sp_executesql`配合输出参数 - 游标循环:将Oracle的游标循环转换为SQL Server的显式游标或使用`WHILE`循环 3. 其他注意事项: - SQL Server中,单引号字符串中的单引号用两个单引号转义 - SQL Server的`GOTO`标签后需要加冒号,且标签名不能加尖括号 - SQL Server的变量名前加`@`符号 - 将Oracle的`SELECT ... INTO`改为SQL Server的`SELECT @var = ...`,并且确保查询返回一行,否则会报错 - 替换特定函数:如`INSTR`->`CHARINDEX`,`SUBSTR`->`SUBSTRING`,`DECODE`->`CASE WHEN`,`NVL`->`ISNULL`等 - 日期函数:`SYSDATE`->`GETDATE()` - 异常消息:原始过程中使用了`IMES.FN_MES_ERROR_CODE_TRANSLATE`函数,在SQL Server中需要替换为对应的错误处理函数或自定义逻辑 由于原始存储过程使用了特定于Oracle的包(如`IMES`下的函数和表),在转换时,我们需要假设这些函数在SQL Server中已有对应实现,或者需要重写这些函数的逻辑。 由于转换涉及较多细节,我们将逐步重写存储过程。 注意:由于无法得知`IMES.SP_MES_GET_STATION_INFO_V1`和`IMES.FN_MES_ERROR_CODE_TRANSLATE`的具体实现,我们只能假设在SQL Server中存在同名的存储过程和函数,或者需要重新实现。这里我们假设这些函数已经存在,且功能相同。 转换后的SQL Server存储过程如下:</think>我将逐步指导您将 Oracle 存储过程转换为 SQL Server 存储过程,重点解决语法差异和功能实现问题: ### 核心语法转换对照表 | **Oracle 语法** | **SQL Server 语法** | **示例** | |----------------|-------------------|----------| | `VARCHAR2` | `NVARCHAR` | `T_SN NVARCHAR(50)` | | `DECLARE` 位置 | 过程开头统一声明 | 所有变量在`AS`后声明 | | `SELECT...INTO` | `SELECT @var=...` | `SELECT @V_WO = WORK_ORDER` | | `||` 字符串连接 | `+` 字符串连接 | `SET @TCONTENT = @TCONTENT + ...` | | `EXECUTE IMMEDIATE` | `sp_executesql` | `EXEC sp_executesql @V_SQL` | | `INSTR()` | `CHARINDEX()` | `CHARINDEX('@SN', @V_SQL)` | | `SUBSTR()` | `SUBSTRING()` | `SUBSTRING(@V_SQL,1,1)` | | `DECODE()` | `CASE WHEN` | `CASE WHEN UPPER(...)` | ### 完整转换步骤 ```sql CREATE PROCEDURE IMES.SP_MES_GET_SN_ATTR_INFO @T_SN NVARCHAR(50), @T_STATIONNAME NVARCHAR(50), @TCONTENT NVARCHAR(MAX) OUTPUT, @TRES NVARCHAR(MAX) OUTPUT AS BEGIN DECLARE @V_COUNT INT, @V_LINE NVARCHAR(50), @V_STAGE NVARCHAR(50), @V_STATION_TYPE NVARCHAR(50), @V_WO NVARCHAR(50), @V_MODEL NVARCHAR(50), @V_WO_LINE NVARCHAR(50), @V_IPN NVARCHAR(50), @V_KOLDATA NVARCHAR(10), @V_SQL NVARCHAR(4000), @V_WO_COLOR NVARCHAR(50), @V_CUSTRULE NVARCHAR(200) SET @TCONTENT = '{' -- 调用子存储过程(需单独转换) EXEC IMES.SP_MES_GET_STATION_INFO_V1 @T_STATIONNAME, @V_LINE OUTPUT, @V_STAGE OUTPUT, @V_STATION_TYPE OUTPUT, @V_MODEL OUTPUT, @TRES OUTPUT IF @TRES <> 'OK' GOTO END_PROC SELECT @V_COUNT = COUNT(1) FROM IMES.P_SN_STATUS WHERE SERIAL_NUMBER = @T_SN IF @V_COUNT = 0 BEGIN SET @TRES = IMES.FN_MES_ERROR_CODE_TRANSLATE('A0001','ZH',@T_SN) GOTO END_PROC END SELECT @V_WO = WORK_ORDER, @V_MODEL = MODEL, @V_IPN = IPN FROM IMES.P_SN_STATUS WHERE SERIAL_NUMBER = @T_SN SET @TCONTENT = @TCONTENT + '"TWO":"' + @V_WO + '"' SET @TCONTENT = @TCONTENT + ',"TMODEL":"' + @V_MODEL + '"' SET @TCONTENT = @TCONTENT + ',"TIPN":"' + @V_IPN + '"' -- 后续转换逻辑类似,主要替换: -- 1. 变量赋值方式:Oracle的 := 改为 SET @var= -- 2. 字符串处理函数 -- 3. 动态SQL执行方式 -- ... (完整转换需约120行) END_PROC: SET @TCONTENT = @TCONTENT + '}' END ``` ### 关键转换技巧 1. **动态SQL处理**: ```sql -- Oracle EXECUTE IMMEDIATE V_SQL INTO V_CUSTRULE; -- SQL Server DECLARE @SQL NVARCHAR(4000) = REPLACE(@V_SQL, '@SN', '''' + @T_SN + '''') EXEC sp_executesql @SQL, N'@V_CUSTRULE NVARCHAR(200) OUTPUT', @V_CUSTRULE OUTPUT ``` 2. **游标循环转换**: ```sql DECLARE cursor_name CURSOR FOR SELECT B.CONFIG_VALUE, B.CONFIG_NAME FROM IMES.M_BLOCK_CONFIG_VALUE B WHERE ... OPEN cursor_name FETCH NEXT FROM cursor_name INTO @ATTR_SQL, @ATTR_NAME WHILE @@FETCH_STATUS = 0 BEGIN -- 处理逻辑 FETCH NEXT FROM cursor_name INTO @ATTR_SQL, @ATTR_NAME END CLOSE cursor_name DEALLOCATE cursor_name ``` 3. **异常处理转换**: ```sql BEGIN TRY -- 主逻辑 END TRY BEGIN CATCH SET @TRES = 'ERROR: ' + ERROR_MESSAGE() END CATCH ``` ### 转换注意事项 1. **数据类型映射**: - `NUMBER` → `INT`/`DECIMAL` - `DATE` → `DATETIME` - `CLOB` → `NVARCHAR(MAX)` 2. **工具辅助**: 使用 [SSMA(SQL Server Migration Assistant)](https://learn.microsoft.com/zh-cn/sql/ssma/oracle/oracle-to-sql-server-migration-assistant) 自动化转换基础语法,手动优化高级特性 3. **性能优化点**: - 将游标操作改为基于集合的操作 - 用`TEMPDB`替代Oracle的全局临时表 - 使用`WITH(NOLOCK)`避免锁争用 > 建议分阶段转换:先转换基础查询 → 处理动态SQL → 实现错误处理 → 性能优化[^1][^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值