可以将此SQL Server存储过程转换为Oracle吗?

时间:2015-12-24 14:16:22

标签: sql-server oracle

我正在尝试将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。你能转换这段代码吗?非常感谢。

1 个答案:

答案 0 :(得分:1)

这在Oracle 11上进行编译。它没有解决临时表的使用问题,如果我理解它应该做什么的话,可以完全废除它。 变更包括:

  • 使用VARCHAR2(4000)代替VARCHAR(MAX)
  • 不要用#开始对象名称,这会让你的生活更轻松
  • 使用“创建”或“替换”启动过程时,必须以“结束”
  • 结束
  • 在程序外移动对象的创建,运行一次,根据需要多次使用该程序
  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;