我正在尝试将SQL Server存储过程转换为Oracle。存储过程的原始代码是1000行,我尝试掌握示例代码中的一些关键功能。关键是声明一些变量,这些变量用于执行一些计数器和条件检查,并创建一些#temp表,用于存储一些中间数据以供以后处理。我想我必须使用这些临时表。
这是SQL Server代码:
CREATE PROCEDURE [dbo].[TestProc]
@InputString VARCHAR(MAX) = ''
AS
DECLARE @DONE INT = 0
DECLARE @I INT = 1; DECLARE @J INT = 1
DECLARE @OutputString VARCHAR(MAX)
SET @OutputString = ''
WHILE @I <= 40000
BEGIN
SET @OutputString = @OutputString + '1234567890'
SET @I = @I + 1
END
--
SET @I = 1
CREATE TABLE #temp1(ID INT IDENTITY(1,1),COL1 VARCHAR(MAX),COL2 VARCHAR(MAX))
WHILE @I <= 10
BEGIN
INSERT INTO #temp1 values(@InputString + '-Col1-'+CAST(@I as VARCHAR(10)),'Col2-'+CAST(@I as VARCHAR(10)))
SET @I = @I + 1
END
--
CREATE TABLE #temp2(ID INT IDENTITY(1,1),COL3 VARCHAR(MAX),COL4 VARCHAR(MAX),COL5 VARCHAR(MAX))
WHILE @J <= 15
BEGIN
INSERT INTO #temp2 values('Col3-'+CAST(@J as VARCHAR(10))
,@OutputString + '-Col4-'+CAST(@J as VARCHAR(10))
, 'Col5-'+CAST(@J as VARCHAR(10)))
SET @J = @J + 1
END
SELECT distinct
temp1.ID
,temp1.Col1
,temp1.COL2
,temp2.Col3
,temp2.Col4
,temp2.Col5
FROM #temp1 temp1
inner join #temp2 temp2
on temp1.ID = temp2.ID
WHERE temp1.ID < 5
GO
要执行存储过程,我使用
exec [dbo].[TestProc] 'testing'
哪种方法正常。
在网络上,我找到了一个SQL转换器,它可以将我的代码转换为Oracle:
CREATE OR REPLACE PROCEDURE TestProc (
p_InputString VARCHAR DEFAULT ''), cur OUT SYS_REFCURSOR
AS
v_DON_ NUMBER(10) := 0;
v_I NUMBER(10) := 1; v_J NUMBER(10) := 1;
v_Out_ VARCHAR(MAX);
BEGIN
v_Out_ := '';
WHILE v_I <= 40000
LOOP
v_Out_ := v_Out_ || '1234567890';
v_I := v_I + 1;
END LOOP;
--
v_I := 1;
CREATE TABLE #temp1(ID NUMBER(10) ,COL1 VARCHAR(MAX),COL2 VARCHAR(MAX));
-- Generate ID using sequence and trigger
CREATE SEQUENCE #temp1_seq START WITH 1 INCREMENT BY 1;
CREATE OR REPLACE TRIGGER #temp1_seq_tr
BEFORE INSERT ON #temp1 FOR EACH ROW
WHEN (NEW.ID IS NULL)
BEGIN
SELECT #temp1_seq.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
/
WHILE v_I <= 10
LOOP
INSERT INTO #temp1 values(p_InputString || '-Col1-'||TO_CHAR(v_I(10)),'Col2-'||TO_CHAR(v_I(10)))
v_I := v_I + 1;
END LOOP;
--
CREATE TABLE #temp2(ID NUMBER(10) ,COL3 VARCHAR(MAX),COL4 VARCHAR(MAX),COL5 VARCHAR(MAX));
-- Generate ID using sequence and trigger
CREATE SEQUENCE #temp2_seq START WITH 1 INCREMENT BY 1;
CREATE OR REPLACE TRIGGER #temp2_seq_tr
BEFORE INSERT ON #temp2 FOR EACH ROW
WHEN (NEW.ID IS NULL)
BEGIN
SELECT #temp2_seq.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
/
WHILE v_J <= 15
LOOP
INSERT INTO #temp2 values('Col3-'||TO_CHAR(v_J(10))
,v_Out_ || '-Col4-'||TO_CHAR(v_J(10))
, 'Col5-'||TO_CHAR(v_J(10)))
v_J := v_J + 1;
END LOOP;
OPEN cur FOR SELECT distinct
temp1.ID
,temp1.Col1
,temp1.COL2
,temp2.Col3
,temp2.Col4
,temp2.Col5
FROM #temp1 temp1
inner join #temp2 temp2
on temp1.ID = temp2.ID
WHERE temp1.ID < 5;
GO
这个Oracle代码对我来说很奇怪。它以Oracle中似乎不允许的方式创建一些临时表。有人可以尝试运行此Oracle代码并查看会发生什么吗?
另外,我希望了解如何将SQL Server存储过程转换为Oracle。你能转换这段代码吗?非常感谢。
答案 0 :(得分:1)
这在Oracle 11上进行编译。它没有解决临时表的使用问题,如果我理解它应该做什么的话,可以完全废除它。 变更包括:
CREATE TABLE temp1(ID NUMBER(10) ,COL1 VARCHAR2(4000),COL2 VARCHAR2(4000));
-- Generate ID using sequence and trigger
CREATE SEQUENCE temp1_seq START WITH 1 INCREMENT BY 1;
CREATE OR REPLACE TRIGGER temp1_seq_tr
BEFORE INSERT ON temp1 FOR EACH ROW
WHEN (NEW.ID IS NULL)
BEGIN
SELECT temp1_seq.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
CREATE TABLE temp2(ID NUMBER(10) ,COL3 VARCHAR2(4000),COL4 VARCHAR2(4000),COL5 VARCHAR2(4000));
-- Generate ID using sequence and trigger
CREATE SEQUENCE temp2_seq START WITH 1 INCREMENT BY 1;
CREATE OR REPLACE TRIGGER temp2_seq_tr
BEFORE INSERT ON temp2 FOR EACH ROW
WHEN (NEW.ID IS NULL)
BEGIN
SELECT temp2_seq.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
/
------------------------------
CREATE OR REPLACE PROCEDURE TESTPROC(P_INPUTSTRING VARCHAR2 DEFAULT '',
CUR OUT SYS_REFCURSOR) AS
V_DON_ NUMBER(10) := 0;
V_I NUMBER(10) := 1;
V_J NUMBER(10) := 1;
V_OUT_ VARCHAR2(4000);
BEGIN
V_OUT_ := '';
WHILE V_I <= 40000 LOOP
V_OUT_ := V_OUT_ || '1234567890';
V_I := V_I + 1;
END LOOP;
--
V_I := 1;
WHILE V_I <= 10 LOOP
INSERT INTO #TEMP1
VALUES
(P_INPUTSTRING || '-Col1-' || TO_CHAR(V_I(10)),
'Col2-' || TO_CHAR(V_I(10))) V_I := V_I + 1;
END LOOP;
--
WHILE V_J <= 15 LOOP
INSERT INTO #TEMP2
VALUES
('Col3-' || TO_CHAR(V_J(10)),
V_OUT_ || '-Col4-' || TO_CHAR(V_J(10)),
'Col5-' || TO_CHAR(V_J(10))) V_J := V_J + 1;
END LOOP;
OPEN CUR FOR
SELECT DISTINCT TEMP1.ID,
TEMP1.COL1,
TEMP1.COL2,
TEMP2.COL3,
TEMP2.COL4,
TEMP2.COL5
FROM #TEMP1 TEMP1
INNER JOIN #TEMP2 TEMP2
ON TEMP1.ID = TEMP2.ID
WHERE TEMP1.ID < 5;
END TESTPROC;