将SQL Server存储过程转换为oracle

时间:2011-01-17 15:02:47

标签: sql-server-2005 oracle stored-procedures

我将以下SP(SQL Server)转换为Oracle。它不编译。 任何建议?????

ALTER PROCEDURE [dbo].[Calendar_GetByDate]
(
   @DueDate datetime,
   @StaffId int,
   @IsForMonth bit,
   @SubpoennaString nvarchar(max),
   @ActivityString nvarchar(max),
   @TrainingString nvarchar(max),
   @RequestString nvarchar(max),
   @OtherString nvarchar(max),
   @CaseOffenseString nvarchar(max),
   @CaseIndividualString nvarchar(max),
   @CaseInvestigationString nvarchar(max),
   @CommunicationLogString nvarchar(max),
   @CrimeSceneString nvarchar(max),
   @CalenderDisplayList nvarchar(100),
   @CalenderCaseId nvarchar(max)=null
)

AS 
BEGIN
    BEGIN TRY
    Declare @dateStr as nvarchar(100)
--select @IsForMonth
    If @IsForMonth = 1
        Begin
            SET @dateStr = 'month'
        END
    ELSE
        BEGIN
            SET @dateStr = 'day'
        END

    DECLARE @str AS nvarchar(max)   
    SET @str = '
                (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' + @SubpoennaString + ' as nvarchar(max)) AS Description
                FROM [Calendar]  WITH (NOLOCK)
                LEFT JOIN SubPoena_Master WITH (NOLOCK) ON [Calendar].EntityId = SubPoena_Master.SPID
                Inner JOIN dbo.fnSplit(''' + @CalenderDisplayList + ''', '','') as FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 3 AND datediff(' + @dateStr + ',[Calendar].[DueDate],''' + cast(@DueDate as nvarchar(20)) + ''') = 0 AND [StaffId] = ' + cast(@StaffId as nvarchar(10)) + '))
            UNION
                (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' + @ActivityString + ' as nvarchar(max)) AS Description
                FROM [Calendar]  WITH (NOLOCK)
                LEFT JOIN Activity WITH (NOLOCK) ON [Calendar].EntityId = Activity.ActivityId
                Inner JOIN dbo.fnSplit(''' + @CalenderDisplayList + ''', '','') as FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 4 AND datediff(' + @dateStr + ',[Calendar].[DueDate],''' + cast(@DueDate as nvarchar(20)) + ''') = 0 AND [StaffId] = ' + cast(@StaffId as nvarchar(10)) + '))
            UNION
                (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' + @CaseOffenseString + ' as nvarchar(max)) AS Description
                FROM [Calendar] WITH (NOLOCK) 
                LEFT JOIN CaseOffense WITH (NOLOCK) ON CaseOffense.CaseOffId = [Calendar].EntityId
                Inner JOIN dbo.fnSplit(''' + @CalenderDisplayList + ''', '','') as FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 5 AND datediff(' + @dateStr + ',[Calendar].[DueDate],''' + cast(@DueDate as nvarchar(20)) + ''') = 0 AND [StaffId] = ' + cast(@StaffId as nvarchar(10)) + ')'

            IF NOT @CalenderCaseId IS NULL
            BEGIN
                SET @str = @str + ' AND [Calendar].CaseId = ''' + @CalenderCaseId + ''''
            END


            SET @str = @str + ')
            UNION
                (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] , cast(' + @CaseIndividualString + ' as nvarchar(max)) AS Description
                FROM [Calendar] WITH (NOLOCK) 
                LEFT JOIN IndividualMaster WITH (NOLOCK) ON IndividualMaster.IndividualId = [Calendar].EntityId
                Inner JOIN dbo.fnSplit(''' + @CalenderDisplayList + ''', '','') as FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 6 AND datediff(' + @dateStr + ',[Calendar].[DueDate],''' + cast(@DueDate as nvarchar(20)) + ''') = 0 AND [StaffId] = ' + cast(@StaffId as nvarchar(10)) + ')'

            IF NOT @CalenderCaseId IS NULL
            BEGIN
                SET @str = @str + ' AND [Calendar].CaseId = ''' + @CalenderCaseId + ''''
            END


            SET @str = @str + ')
            UNION
                (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' + @CaseInvestigationString + ' as nvarchar(max)) AS Description
                FROM [Calendar] WITH (NOLOCK) 
                LEFT JOIN CaseInvestigation WITH (NOLOCK) ON [Calendar].EntityId = CaseInvestigation.InvestigationId
                Inner JOIN dbo.fnSplit(''' + @CalenderDisplayList + ''', '','') as FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 7 AND datediff(' + @dateStr + ',[Calendar].[DueDate],''' + cast(@DueDate as nvarchar(20)) + ''') = 0 AND [StaffId] = ' + cast(@StaffId as nvarchar(10)) + ')'

            IF NOT @CalenderCaseId IS NULL
            BEGIN
                SET @str = @str + ' AND [Calendar].CaseId = ''' + @CalenderCaseId + ''''
            END


            SET @str = @str + ')
            UNION
                (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' + @CommunicationLogString + ' as nvarchar(max)) AS Description
                FROM [Calendar] WITH (NOLOCK) 
                LEFT JOIN CommunicationLog WITH (NOLOCK) ON [Calendar].EntityId = CommunicationLog.LogId
                Inner JOIN dbo.fnSplit(''' + @CalenderDisplayList + ''', '','') as FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 8 AND datediff(' + @dateStr + ',[Calendar].[DueDate],''' + cast(@DueDate as nvarchar(20)) + ''') = 0 AND [StaffId] = ' + cast(@StaffId as nvarchar(10)) + ')'
            IF NOT @CalenderCaseId IS NULL
            BEGIN
                SET @str = @str + ' AND [Calendar].CaseId = ''' + @CalenderCaseId + ''''
            END


            SET @str = @str + ')
            UNION
                (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' + @CrimeSceneString + ' as nvarchar(max)) AS Description
                FROM [Calendar]  WITH (NOLOCK)
                LEFT JOIN Scene WITH (NOLOCK) ON [Calendar].EntityId = Scene.CrimeSceneId
                Inner JOIN dbo.fnSplit(''' + @CalenderDisplayList + ''', '','') as FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 9 AND datediff(' + @dateStr + ',[Calendar].[DueDate],''' + cast(@DueDate as nvarchar(20)) + ''') = 0 AND [StaffId] = ' + cast(@StaffId as nvarchar(10)) + ')'

            IF NOT @CalenderCaseId IS NULL
            BEGIN
                SET @str = @str + ' AND [Calendar].CaseId = ''' + @CalenderCaseId + ''''
            END

            SET @str = @str + ')


ORDER BY [Calendar].[DueDate]
'
--select @str   
exec (@str)

    END TRY

    BEGIN CATCH
        SELECT  ERROR_MESSAGE() as ErrorMessage;
    END CATCH


    RETURN 
END

ORACLE的存储过程

CREATE OR REPLACE PROCEDURE ADMIN.Calendar_GetByDate(DueDate IN TIMESTAMP,
   StaffId IN NUMBER,
   IsForMonth IN NUMBER,
   SubpoennaString IN nvarchar2,
   ActivityString IN nvarchar2,
   TrainingString IN nvarchar2,
   RequestString IN nvarchar2,
   OtherString IN nvarchar2,
   CaseOffenseString IN nvarchar2,
   CaseIndividualString IN nvarchar2,
   CaseInvestigationString IN nvarchar2,
   CommunicationLogString IN nvarchar2,
   CrimeSceneString IN nvarchar2,
   CalenderDisplayList IN NVARCHAR2,
   CalenderCaseId IN nvarchar2 DEFAULT null, v_refcur OUT SYS_REFCURSOR)

   as
   dateStr  NVARCHAR2(100);
   str  nvarchar2(32000);

   SWV_VarStr varchar2(32000);
   str1 varchar2(32000);
BEGIN
   BEGIN
      If IsForMonth = 1 then

         dateStr := 'month';
      ELSE
         dateStr := 'day';
      end if;
      str := ' SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' || SubpoennaString || ' as nvarchar2(4000)) AS Description
                FROM [Calendar]  WITH (NOLOCK)
                LEFT JOIN SubPoena_Master WITH (NOLOCK) ON [Calendar].EntityId = SubPoena_Master.SPID
                Inner JOIN dbo.fnSplit(''' || CalenderDisplayList || ''', '','') as FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 3 AND datediff(' || dateStr || ',[Calendar].[DueDate],''' || SUBSTR(cast(DueDate as NVARCHAR2),1,20) || ''') = 0 AND StaffId = ' || SUBSTR(cast(StaffId as NVARCHAR2),1,10) || '))     UNION   (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' || ActivityString || 'as nvarchar2(4000)) AS Description
                FROM [Calendar]  WITH (NOLOCK)
                LEFT JOIN Activity WITH (NOLOCK) ON [Calendar].EntityId = Activity.ActivityId
                Inner JOIN dbo.fnSplit(''' || CalenderDisplayList || ''','','') AS FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 4 AND datediff(' || dateStr || ',[Calendar].[DueDate],''' || SUBSTR(cast(DueDate as NVARCHAR2),1,20) || ''') = 0 AND StaffId = ' || SUBSTR(cast(StaffId as NVARCHAR2),1,10) || '))     UNION   (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' || CaseOffenseString || 'as nvarchar2(4000)) AS Description
                FROM [Calendar] WITH (NOLOCK) 
                LEFT JOIN CaseOffense WITH (NOLOCK) ON CaseOffense.CaseOffId = [Calendar].EntityId
                Inner JOIN dbo.fnSplit(''' || CalenderDisplayList || ''','','') AS FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 5 AND datediff(' || dateStr || ',[Calendar].[DueDate],''' || SUBSTR(cast(DueDate as NVARCHAR2),1,20) || ''') = 0 AND StaffId = ' || SUBSTR(cast(StaffId as NVARCHAR2),1,10) || ')';
      IF NOT CalenderCaseId IS NULL then

         str := str || ' AND [Calendar].CaseId =  ''' || CalenderCaseId || '''';
      end if;
      str := str || 'UNION  (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] , cast(' || CaseIndividualString || 'as nvarchar2(4000)) AS Description
                FROM [Calendar] WITH (NOLOCK) 
                LEFT JOIN IndividualMaster WITH (NOLOCK) ON IndividualMaster.IndividualId = [Calendar].EntityId
                Inner JOIN dbo.fnSplit(''' || CalenderDisplayList || ''','','') AS FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 6 AND datediff(' || dateStr || '[Calendar].[DueDate],''' || SUBSTR(cast(DueDate as NVARCHAR2),1,20) || ''') = 0 AND StaffId = ' || SUBSTR(cast(StaffId as NVARCHAR2),1,10) || ')';
      IF NOT CalenderCaseId IS NULL then

         str := str || ' AND [Calendar].CaseId = ''' || CalenderCaseId || '''';
      end if;
      str := str || 'UNION  (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' || CaseInvestigationString || ' as nvarchar2(4000)) AS Description
                FROM [Calendar] WITH (NOLOCK) 
                LEFT JOIN CaseInvestigation WITH (NOLOCK) ON [Calendar].EntityId = CaseInvestigation.InvestigationId
                Inner JOIN dbo.fnSplit(''' || CalenderDisplayList || ''','','') AS FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 7 AND datediff(' || dateStr || ',[Calendar].[DueDate],''' || SUBSTR(cast(DueDate as NVARCHAR2),1,20) || ''') = 0 AND [StaffId] = ' || SUBSTR(cast(StaffId as NVARCHAR2),1,10) || ')';
      IF NOT CalenderCaseId IS NULL then

         str := str || ' AND [Calendar].CaseId = ''' || CalenderCaseId || '''';
      end if;
      str1 :=  'UNION   (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' || CommunicationLogString || ' as nvarchar2(4000)) AS Description
                FROM [Calendar] WITH (NOLOCK) 
                LEFT JOIN CommunicationLog WITH (NOLOCK) ON [Calendar].EntityId = CommunicationLog.LogId
                Inner JOIN dbo.fnSplit(''' || CalenderDisplayList || ''','','') AS FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 8 AND datediff(' || dateStr || ',[Calendar].[DueDate],''' || SUBSTR(cast(DueDate as NVARCHAR2),1,20) || ''') = 0 AND [StaffId] = ' || SUBSTR(cast(StaffId as NVARCHAR2),1,10) || ')';
      IF NOT CalenderCaseId IS NULL then

         str1 := str1 || ' AND [Calendar].CaseId = ''' || CalenderCaseId || '''';
      end if;
      str1 := str1 || 'UNION    (SELECT [Calendar].[CalendarId], [Calendar].[EntityTypeId],
                  [Calendar].[EntityId], [Calendar].[StaffId], [Calendar].[CaseId],
                  [Calendar].[DueDate], [Calendar].[IsActive], [Calendar].[IsCaseCalendar],
                  [Calendar].[LastUpdatedBy], [Calendar].[LastUpdateDate] ,  cast(' || CrimeSceneString || ' as nvarchar2(4000)) AS Description
                FROM [Calendar]  WITH (NOLOCK)
                LEFT JOIN Scene WITH (NOLOCK) ON [Calendar].EntityId = Scene.CrimeSceneId
                Inner JOIN dbo.fnSplit(''' || CalenderDisplayList || ''','','') AS FN on FN.ItemValue = [Calendar].EntityTypeId
                WHERE ([Calendar].EntityTypeId = 9 AND datediff(' || dateStr || ',[Calendar].[DueDate],''' || SUBSTR(cast(DueDate as NVARCHAR2),1,20) || ''') = 0 AND [StaffId] = ' || SUBSTR(cast(StaffId as NVARCHAR2),1,10) || ')';
      IF NOT CalenderCaseId IS NULL then

         str1 := str1 || ' AND [Calendar].CaseId = ''' || CalenderCaseId || '''';
      end if;
      str1 := str1 || ') ORDER BY [Calendar].[DueDate]';
--select @str   
      SWV_VarStr := str || str1;
      EXECUTE IMMEDIATE SWV_VarStr;


   END;


   RETURN; 
END;
/

2 个答案:

答案 0 :(得分:3)

您尚未将SQL转换为Oracle:

  • 没有像Oracle中的DATEDIFF这样的功能
  • WITH(NOLOCK)在Oracle中无效
  • [TableName]。[ColumnName]语法在Oracle
  • 中无效

答案 1 :(得分:2)

当您想将TSQL迁移到Oracle时,我建议您首先以最友好的Orcale方式重写SQL代码。

第一个观察是,您将所有字符串参数声明为varchar(max)。如果你的代码必须在SQL-Server-2005上运行,你会怎么做?你会选择varchar(8000),nvarchar(4000),text还是ntext?

varchar(4000)或nvarchar(4000)是否可以接受?

这不是长度问题,而是数据类型的问题。你需要丑陋的CLOB参数还是可以使用漂亮的varchar2?

好消息: Oracle并不关心varchar2参数的长度。你不玩游戏。我们刚刚将column_x的列大小增加了10(我们不想浪费您知道的存储空间),现在您可以使用该列调整这10个存储过程。

第二次最好从您的TSQL中删除所有方括号 [] ,如果您依赖它们,在迁移到Oracle时肯定会遇到一些麻烦。

第三次问问自己树时,如果你真的想使用动态sql。在对您的代码进行一瞥之后,我想我会尝试将其重写为直接TSQ,也许使用一些if else逻辑。你可能会问为什么。答案是为了表现。我只提到关键字:绑定变量,上下文,共享池。 Oracle有一个有限的资源,称为共享池,当您从sql-server以简单直接的方式迁移动态sql时,它往往会成为瓶颈。相信我更好地调整你的SQL不使用动态sql而不是照顾Oracle的特殊需求。

Forth 使用两个系统中相似的构造

  • 分析功能
  • 公用表表达式(在Oracle文档中称为子查询因子)