PL / SQL到TSQL的转换

时间:2014-05-23 02:53:00

标签: sql-server sql-server-2008 tsql case data-conversion

我使用了一个工具将PL / SQL转换为TSQL,但在某些情况下我遇到了奇怪的错误。

CREATE PROC Dates
(
    @PeriodType varchar(15),
    @ReportStart varchar(15),
    @ReportEnd varchar(15)
)
AS
BEGIN
    SELECT CASE
               WHEN @PeriodType  = 'CUR_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 1 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112))
               WHEN @PeriodType  = 'NEXT_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 8 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112))
               WHEN @PeriodType  = 'PREV_DAY' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 1, 112))
               WHEN @PeriodType  = 'PREV_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 6 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112))
               WHEN @PeriodType  = 'PREV_2WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 13, 112))
               WHEN @PeriodType  = 'CUR_MONTH' THEN CONVERT(DATETIME, CAST(CONVERT(VARCHAR(23), GETDATE()) AS VARCHAR) + '01', 112)
               WHEN @PeriodType  = 'DATE_RANGE' THEN CONVERT(DATETIME, @ReportStart)
           END AS "StartDate",
           CASE
               WHEN @PeriodType  = 'CUR_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 8 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112)) - (1 / CONVERT(FLOAT, 86400))
               WHEN @PeriodType  = 'NEXT_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 15 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112)) - (1 / CONVERT(FLOAT, 86400))
               WHEN @PeriodType  = 'PREV_DAY' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE(), 112)) - (1 / CONVERT(FLOAT, 86400))
               WHEN @PeriodType  = 'PREV_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112)) + 1 - (1 / CONVERT(FLOAT, 86400))
               WHEN @PeriodType  = 'PREV_2WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 1, 112)) - (1 / CONVERT(FLOAT, 86400))
               WHEN @PeriodType  = 'CUR_MONTH' THEN DATEADD(M, 1, CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE(), 112)) - (CONVERT(NUMERIC(8, 2), DATEPART(DD, GETDATE())) - 1)) - 1
               WHEN @PeriodType  = 'DATE_RANGE' THEN CONVERT(DATETIME, @ReportEnd) + 1
           END AS "EndDate"
END

我的存储过程正在执行PREV_DAY和PREV_2WEEK,因为其余的句号类型我收到了转换错误。

exec proc Dates 'PREV_DAY','',''
exec proc Dates 'PREV_2WEEK','',''

我的PL \ SQL代码是

 SELECT CASE 
            WHEN :PeriodType = 'CUR_WEEK'
                 THEN TRUNC(SYSDATE + 1 - TO_NUMBER(TO_CHAR(SYSDATE, 'D')))
            WHEN :PeriodType = 'NEXT_WEEK'
                 THEN TRUNC(SYSDATE + 8 - TO_NUMBER(TO_CHAR(SYSDATE, 'D')))
            WHEN :PeriodType = 'PREV_DAY'
                 THEN TRUNC(SYSDATE - 1)
            WHEN :PeriodType = 'PREV_WEEK'
                 THEN TRUNC(SYSDATE - 6 - TO_NUMBER(TO_CHAR(SYSDATE, 'D')))
            WHEN :PeriodType = 'PREV_2WEEK'
                 THEN TRUNC(SYSDATE - 13)
            WHEN :PeriodType = 'CUR_MONTH'
                 THEN to_date(to_char(sysdate,'YYYYMM') || '01','YYYYMMDD')
            WHEN :PeriodType = 'DATE_RANGE'
                 THEN TO_DATE(:ReportStart)
        END  AS "StartDate",
        CASE
            WHEN :PeriodType = 'CUR_WEEK'
                 THEN TRUNC(SYSDATE + 8 - TO_NUMBER(TO_CHAR(SYSDATE, 'D'))) - (1/86400)
            WHEN :PeriodType = 'NEXT_WEEK'
                 THEN TRUNC(SYSDATE + 15 - TO_NUMBER(TO_CHAR(SYSDATE, 'D'))) - (1/86400)
            WHEN :PeriodType = 'PREV_DAY'
                 THEN TRUNC(SYSDATE)-(1/86400)
            WHEN :PeriodType = 'PREV_WEEK'
                 THEN TRUNC(SYSDATE - TO_NUMBER(TO_CHAR(SYSDATE, 'D'))) + 1 - (1/86400)
            WHEN :PeriodType = 'PREV_2WEEK'
                 THEN TRUNC ( SYSDATE+1) - (1/86400)
            WHEN :PeriodType = 'CUR_MONTH'
                 THEN ADD_MONTHS(TRUNC(SYSDATE) - (TO_NUMBER(TO_CHAR(SYSDATE,'DD')) - 1), 1) -1
            WHEN :PeriodType = 'DATE_RANGE'
                 THEN TO_DATE(:ReportEnd)+1
        END AS "EndDate"
   FROM DUAL

2 个答案:

答案 0 :(得分:3)

第一个then子句中至少有一个问题是这个表达式:

CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE()))

这个表达式:

select CONVERT(VARCHAR(23), GETDATE())

刚回来:

May 23 2014 3:01AM

而这只是没有转换为数字。

我认为您需要逐行检查代码以找出最佳的处理方式。此外,无论何时使用varcharchar,都应该有与之关联的长度。默认值有时(但不总是)为1,这可能会导致问题。

答案 1 :(得分:2)

Oracle和SQLServer以不同的方式使用datetime。

该工具转换了脚本以及字符串解析器,就像有人在两种语言之间逐字翻译报价一样。

在SQLServer中使用该数据类型时,您必须使用DATEADDDATEDIFF和其他可以在MS的help page上找到的函数。

使用SQLServer的日期函数将原始函数转换为

CREATE PROC Dates(
@PeriodType varchar(15),
@ReportStart varchar(15),
@ReportEnd varchar(15)
)
AS
BEGIN
  SELECT CASE WHEN @PeriodType = 'CUR_WEEK' THEN DATEADD(DAY, - DATEPART(dw, GETDATE()) + 1, cast(cast(GETDATE() AS date) AS datetime))
              WHEN @PeriodType = 'NEXT_WEEK' THEN DATEADD(DAY, 8 - DATEPART(dw, GETDATE()), cast(cast(GETDATE() AS date) AS datetime))
              WHEN @PeriodType = 'PREV_DAY' THEN DATEADD(DAY, -1, cast(cast(GETDATE() AS date) AS datetime))
              WHEN @PeriodType = 'PREV_WEEK' THEN DATEADD(DAY, - DATEPART(dw, GETDATE()) - 6, cast(cast(GETDATE() AS date) AS datetime))
              WHEN @PeriodType = 'PREV_2WEEK' THEN DATEADD(DAY, - 13, cast(cast(GETDATE() AS date) AS datetime))
              WHEN @PeriodType = 'CUR_MONTH' THEN DATEADD(DAY, - DATEPART(DAY, GETDATE()) + 1, cast(cast(GETDATE() AS date) AS datetime))
              WHEN @PeriodType = 'DATE_RANGE' THEN CONVERT(DATETIME, @ReportStart)
         END AS StartDate,
       , CASE WHEN @PeriodType = 'CUR_WEEK' THEN DATEADD(mi, -1, DATEADD(DAY, 8 - DATEPART(dw, GETDATE()), cast(cast(GETDATE() AS date) AS datetime)))
              WHEN @PeriodType = 'NEXT_WEEK' THEN DATEADD(mi, -1, DATEADD(DAY, 15 - DATEPART(dw, GETDATE()), cast(cast(GETDATE() AS date) AS datetime)))
              WHEN @PeriodType = 'PREV_DAY' THEN DATEADD(mi, -1,  DATEADD(DAY, - DATEPART(dw, GETDATE()) + 1, cast(cast(GETDATE() AS date) AS datetime)))
              WHEN @PeriodType = 'PREV_WEEK' THEN DATEADD(mi, -1, DATEADD(DAY, 8 - DATEPART(dw, GETDATE()), cast(cast(GETDATE() AS date) AS datetime)))
              WHEN @PeriodType = 'PREV_2WEEK' THEN DATEADD(mi, -1, cast(cast(dateadd(DAY, 1, GETDATE()) AS date) AS datetime))
              WHEN @PeriodType = 'CUR_MONTH' THEN DATEADD(DAY, -1, DATEADD(mm, DATEDIFF(mm, 0, cast(cast(GETDATE() AS date) AS datetime))+1,0))
              WHEN @PeriodType = 'DATE_RANGE' THEN CONVERT(DATETIME, @ReportEnd) + 1
         END AS EndDate
END

CAST中的双CAST(CAST(GETDATE() AS DATE) AS DATETIME)有点破解今天的午夜,因为GETDATE()是日期时间类型并返回当前日期和时间