【问题标题】:Convert stored procedure from Oracle to SQL Server with Oracle-To-SqlServer Migration Tool使用 Oracle-To-SqlServer 迁移工具将存储过程从 Oracle 转换为 SQL Server
【发布时间】:2023-04-11 01:46:01
【问题描述】:

我使用 Oracle-To-SqlServer 迁移工具转换了下面的存储过程,但无法正确转换:

CREATE OR REPLACE PROCEDURE sp_Get_count(
ClientCountout OUT VARCHAR2
)
is

--Quarter VARCHAR2(20);
--ClientCount VARCHAR2(20);

--
--Quarterout VARCHAR2(20);
--ClientCountout VARCHAR2(20);

varQuarter VARCHAR2(20);
varStart_Date VARCHAR2(20);
varEnd_Date VARCHAR2(20);

CURSOR cr_client
   IS
    with dates as (
    select to_date('1-Jan-2012', 'dd-mon-yyyy', 'nls_date_language =american') startdate 
    ,      to_date('31-Mar-2012', 'dd-mon-yyyy', 'nls_date_language =american') enddate
    from   dual
    )
    Select to_char(to_date(Start_Date,'dd-mon-yyyy'), 'YYYY-Q') Quarter, Start_Date, End_Date from 
    (select to_char(add_months(startdate, level*3-3), 'DD-MON-YYYY') Start_Date,
           to_char(add_months(enddate, level*3-3), 'DD-MON-YYYY') End_Date
    from   dates
    connect by level <= 10) ; 

 BEGIN

            OPEN cr_client;

     IF cr_client%ISOPEN
       THEN
          LOOP        
            FETCH cr_client
                      INTO varQuarter, varStart_Date,varEnd_Date ;   
            EXIT WHEN cr_client%NOTFOUND;

       ClientCountout:= USER_BUILDER.get_Client_Count(varStart_Date ,varEnd_Date) ; 

       dbms_output.put_line('Client Count for: ' || varQuarter || ' is '|| ClientCountout);

  END LOOP;

  CLOSE cr_client;
   END IF;
END;

以下是转换后的 SQL Server 存储过程:

CREATE PROCEDURE USER_BUILDER.sp_Get_count
   @CLIENTCOUNTOUT varchar(max)  OUTPUT
AS 
   /*Generated by SQL Server Migration Assistant for Oracle version 7.8.0.*/
   BEGIN
      SET @CLIENTCOUNTOUT = NULL

      /*
      *   Quarter VARCHAR2(20);
      *   ClientCount VARCHAR2(20);
      *
      *   Quarterout VARCHAR2(20);
      *   ClientCountout VARCHAR2(20);
      */
      DECLARE
         @VARQUARTER varchar(20), 
         @VARSTART_DATE varchar(20), 
         @VAREND_DATE varchar(20)

      /* 
      *   SSMA error messages:
      *   O2SS0208: Subquery factoring clause conversion is not supported. 
      *   WITH dates
      *      (
      *         SELECT to_date('1-Jan-2012', 'dd-mon-yyyy', 'nls_date_language =american') startdate, to_date('31-Mar-2012', 'dd-mon-yyyy', 'nls_date_language =american') enddate
      *         FROM dual
      *      ), AS

      DECLARE
          CR_CLIENT CURSOR LOCAL FOR 
            WITH 
               h$cte AS 
               (
                  SELECT DATES.STARTDATE, DATES.ENDDATE, 1 AS LEVEL, CAST(row_number() OVER(
                     ORDER BY @@spid) AS varchar(max)) AS path
                  FROM DATES
                   UNION ALL
                  SELECT DATES.STARTDATE, DATES.ENDDATE, h$cte.LEVEL + 1 AS LEVEL, path + ',' + CAST(row_number() OVER(
                     ORDER BY @@spid) AS varchar(max)) AS path
                  FROM DATES, h$cte
                  WHERE LEVEL <= 10
               )

               SELECT ssma_oracle.to_char_date(ssma_oracle.to_date2(fci.START_DATE, 'dd-mon-yyyy'), 'YYYY-Q') AS QUARTER, fci.START_DATE, fci.END_DATE
               FROM 
                  (
                     SELECT TOP 9223372036854775807 ssma_oracle.to_char_date(dateadd(m, h$cte.LEVEL * 3 - 3, h$cte.STARTDATE), 'DD-MON-YYYY') AS START_DATE, ssma_oracle.to_char_date(dateadd(m, h$cte.LEVEL * 3 - 3, h$cte.ENDDATE), 'DD-MON-YYYY') AS END_DATE
                     FROM h$cte
                     ORDER BY h$cte.path
                  )  AS fci      */



      OPEN CR_CLIENT

      IF CURSOR_STATUS('local', N'CR_CLIENT') > -1
         BEGIN

            WHILE 1 = 1

               BEGIN

                  FETCH CR_CLIENT
                      INTO @VARQUARTER, @VARSTART_DATE, @VAREND_DATE

                  /*
                  *   SSMA warning messages:
                  *   O2SS0113: The value of @@FETCH_STATUS might be changed by previous FETCH operations on other cursors, if the cursors are used simultaneously.
                  */

                  IF @@FETCH_STATUS <> 0
                     BREAK

                  /* 
                  *   SSMA error messages:
                  *   O2SS0556: Identifier USER_BUILDER.get_Client_Count cannot be converted because it was not resolved.
                  *   This may happen because referenced object is missing from the database.
                  *   It is recommended to fix and recompile all invalid objects in Oracle before attempting a conversion.
                  *

                  SET @CLIENTCOUNTOUT = USER_BUILDER.GET_CLIENT_COUNT                  */



                  PRINT 'Client Count for: ' + ISNULL(@VARQUARTER, '') + ' is ' + ISNULL(@CLIENTCOUNTOUT, '')

               END

            CLOSE CR_CLIENT

            DEALLOCATE CR_CLIENT

         END

   END

如果您检查 SQL Server 转换的存储过程,您将看到“SSMA 错误消息”,详细信息为“O2SS0208:不支持子查询分解子句转换”,并且查询已被迁移工具注释。

谢谢

【问题讨论】:

  • 描述存储过程应该做什么。提供样本数据和期望的结果。
  • 实际上我已经获得了带有空表的数据库,存储过程。我现在的工作是转换存储过程并正确执行它们而不用担心数据。
  • 你打算如何在没有任何数据的情况下测试执行?

标签: c# sql sql-server database-migration oracle12c


【解决方案1】:

您需要一个 Oracle 实例来测试和转换。如果您不能在 Oracle 上运行查询并检查结果,就要求您创建正确的转换是不合理的。通常,此过程是构建一个日历,然后为每一行运行另一个存储过程。

这是与该 Oracle 查询等效的 SQL Server 上的第一次通过,模数错误和较小的格式差异(您需要针对 Oracle 实例进行测试以验证)。

with dates as 
(
    select cast('2012-01-01' as datetime) startdate, cast('2012-03-01' as datetime) enddate
),
levels as (
      select * from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) v(level)
)
Select concat(year(start_date),'-',1+(month(start_date)-1)/3) Quarter, format(Start_Date,'dd-MM-yyyy') Start_Date , format(End_Date,'dd-MM-yyyy') End_Date
from 
(select dateadd(month,level*3-3,startdate ) Start_Date,
        dateadd(month, level*3-3,enddate) End_Date
from   dates, levels ) d
order by start_date 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 2018-05-06
    • 2018-09-18
    • 2020-10-12
    • 1970-01-01
    • 2015-11-30
    • 2021-08-17
    相关资源
    最近更新 更多