请求将两段SQL更新语句转换为Oracle PL/SQL代码
SQL Server UPDATE语句转Oracle PL/SQL实现
第一段UPDATE转换
原SQL为单条考勤记录更新,转换后的PL/SQL代码如下:
DECLARE v_shift_name Attendance.ShiftName%TYPE; v_updated_by Attendance.ModifiedBy%TYPE; v_attendance_id Attendance.AttendanceId%TYPE; BEGIN -- 实际使用时替换为传入参数 v_shift_name := '传入的班次名称'; v_updated_by := '更新人账号'; v_attendance_id := 12345; UPDATE Attendance A SET ShiftName = v_shift_name, ShiftStartTime = TRUNC(A.AttendanceDate) + TO_DATE(S.ShiftStartTime, 'HH24:MI:SS'), ShiftEndTime = TRUNC(A.AttendanceDate) + CASE WHEN v_shift_name = 'NIGHT' THEN INTERVAL '-1' DAY ELSE INTERVAL '0' DAY END + TO_DATE(S.ShiftEndTime, 'HH24:MI:SS'), ModifiedBy = v_updated_by, ModifiedOn = SYSDATE FROM ShiftMaster S WHERE S."Shift" = v_shift_name AND A.AttendanceId = v_attendance_id; COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END; /
转换要点:
- 替换SQL Server的
GETDATE()为Oracle的SYSDATE - 将
DATEADD/DATEDIFF拼接日期+时间的逻辑,改为TRUNC(日期字段)提取纯日期部分,加上TO_DATE(时间字符串, 'HH24:MI:SS')转换的时间间隔 - 使用PL/SQL变量声明语法,通过
%TYPE关联表字段类型,保证类型兼容 - Oracle 12c及以上版本支持
UPDATE ... FROM语法,直接适配原SQL的关联逻辑
第二段UPDATE转换
原SQL为批量关联表变量的考勤记录更新,转换后的PL/SQL代码如下(用临时表模拟SQL Server表变量):
-- 创建临时表模拟SQL Server的@dtAttendance表变量 CREATE GLOBAL TEMPORARY TABLE temp_attendance ( LoginID VARCHAR2(100), AttendanceDate DATE, ShiftName VARCHAR2(100) ) ON COMMIT DELETE ROWS; -- 向临时表插入数据(实际使用时替换为业务数据) INSERT INTO temp_attendance (LoginID, AttendanceDate, ShiftName) VALUES ('USER_001', SYSDATE, 'DAY'), ('USER_002', SYSDATE+1, 'NIGHT'); DECLARE v_updated_by VARCHAR2(100); v_tower_pk UserAttendanceTeam.TowerPk%TYPE; BEGIN v_updated_by := '更新人账号'; v_tower_pk := 'TOWER_001'; MERGE INTO Attendance A USING ( SELECT dt.LoginID, dt.AttendanceDate, dt.ShiftName, S.ShiftStartTime, S.ShiftEndTime FROM temp_attendance dt LEFT JOIN ShiftMaster S ON S."Shift" = dt.ShiftName WHERE dt.AttendanceDate BETWEEN SYSDATE - 1 AND SYSDATE + INTERVAL '30' DAY AND dt.LoginID IN (SELECT LoginId FROM UserAttendanceTeam WHERE TowerPk = v_tower_pk AND isActive = 'Y') ) src ON (A.LoginId = src.LoginID AND A.AttendanceDate = src.AttendanceDate) WHEN MATCHED THEN UPDATE SET A.ShiftName = src.ShiftName, A.ShiftStartTime = TRUNC(A.AttendanceDate) + TO_DATE(src.ShiftStartTime, 'HH24:MI:SS'), A.ShiftEndTime = TRUNC(A.AttendanceDate) + CASE WHEN src.ShiftName = 'NIGHT' THEN INTERVAL '-1' DAY ELSE INTERVAL '0' DAY END + TO_DATE(src.ShiftEndTime, 'HH24:MI:SS'), A.ModifiedBy = v_updated_by, A.ModifiedOn = SYSDATE; COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END; /
转换要点:
- 用Oracle临时表替代SQL Server表变量
@dtAttendance,也可根据业务需求改用集合类型 - 多表关联更新使用Oracle推荐的
MERGE语句,适配原SQL的JOIN逻辑 - 日期范围条件
getdate()-1替换为SYSDATE - 1,dateadd(day,+30,getdate())替换为SYSDATE + INTERVAL '30' DAY - 保留原SQL的子查询过滤逻辑,注意Oracle对象名大小写(若用双引号创建需保持一致)
内容的提问来源于stack exchange,提问作者sudhir mishra
相关产品推荐
相关产品推荐

