2013-01-14 32 views
0

我需要从两个表中编译数据,但没有任何共同之处。在SQL Server 2008 R2中使用CASE更改日期

要做到这一点,我创建了一个视图,提取我需要的位,它是交叉连接的,所以我需要通过过滤日期去除不必要的行。

但是,我发现日期有问题。

基本上,一些用户必须在他们的系统上设置US格式,这就是日期如何进入数据库(m/d/yyyy)。

绝大多数日期是在英国的格式(dd/mm/yyyy

显然(正确),我需要所有日期是在相同的格式,但CONVERT和CAST似乎并不管用。

因此,我想出了使用CASE来确定字符串长度和内容的想法。

基本上,我寻找长度10(例如15/01/2012),并假定它是一个正确的(UK)日期,除非字符4 & 5是大于12

如果它是9个字符长,那么我需要查找第一个'/'的位置,它告诉我它是d/mm还是dd/m(年份总是4个字符)。

最后,如果它的长度为8个字符,我认为它必须是不正确的(美国)日期,并将数字反向,将零填充为填充符。

然而,当我尝试运行脚本,它给了我:

Msg 102, Level 15, State 1, Line 12 
Incorrect syntax near '='. 
Msg 156, Level 15, State 1, Line 16 
Incorrect syntax near the keyword 'THEN'. 
Msg 4145, Level 15, State 1, Line 22 
An expression of non-boolean type specified in a context where a condition is expected, near 'ELSE'. 
Msg 102, Level 15, State 1, Line 24 
Incorrect syntax near '@Day'. 
Msg 4145, Level 15, State 1, Line 29 
An expression of non-boolean type specified in a context where a condition is expected, near 'END'. 
Msg 156, Level 15, State 1, Line 39 
Incorrect syntax near the keyword 'IF'. 
Msg 102, Level 15, State 1, Line 40 
Incorrect syntax near ','. 
Msg 102, Level 15, State 1, Line 41 
Incorrect syntax near ','. 
Msg 102, Level 15, State 1, Line 46 
Incorrect syntax near ','. 
Msg 156, Level 15, State 1, Line 50 
Incorrect syntax near the keyword 'THEN'. 
Msg 102, Level 15, State 1, Line 51 
Incorrect syntax near ','. 
Msg 102, Level 15, State 1, Line 52 
Incorrect syntax near ','. 

是失败的是下面的脚本的一部分,我希望有人有什么,我需要做一个建议与它(或确实,更好的方式来整理日期)。

我试图做到的,是直接从源表(mbrProject),其中ID的比赛(我已经填充了ID的新填充的新表(或视图)[START_DATE]字段表由mbrProject选择不同),也尝试应用在飞行的日期格式变化:

declare @length int, 
    @Day nchar(3), 
    @Month nchar(3), 
    @Year nchar(5) 

Update ProjectDates 
SET [Start_Date] = 
(CASE 
    WHEN len(mbrProject.[Start_Date]) = 8 THEN 
     @Day = '0' & SUBSTRING(mbrProject.[START_DATE],3,2), @Month = '0' & SUBSTRING(mbrProject.[START_DATE],1,2), @Year = right(mbrProject.[START_DATE],5) 
     @Day + @Month + @Year 

    WHEN len(mbrProject.[Start_Date]) = 9 THEN 
     IF charindex('/',mbrProject.[start_date]) = 2 THEN 
     @Day = SUBSTRING(mbrProject.[START_DATE],3,3), @Month = '0' & SUBSTRING(mbrProject.[START_DATE],1,2), @Year = right(mbrProject.[START_DATE],5) 
     ELSE @Day = '0' & SUBSTRING(mbrProject.[START_DATE],4,2), @Month = SUBSTRING(mbrProject.[START_DATE],1,3), @Year = right(mbrProject.[START_DATE],5) 
     END IF 
     @Day + @Month + @Year 

    ELSE 
     IF SUBSTRING(mbrProject.[START_DATE],4,2) > 12 
      @Day = SUBSTRING(mbrProject.[START_DATE],4,3), @Month = SUBSTRING(mbrProject.[START_DATE],1,3), @Year = right(mbrProject.[START_DATE],5) 
      ELSE @Day = SUBSTRING(mbrProject.[START_DATE],1,3), @Month = SUBSTRING(mbrProject.[START_DATE],4,3), @Year = right(mbrProject.[START_DATE],5) 
     END IF 
     @Day + @Month + @Year 

    END) 

Where ProjectDates.[START_DATE] = mbrProject.[START_DATE] 

====================== =================================================

**编辑**

好的,非常感谢Kaf。 我使用通用脚本来创建一个新的uodate脚本,但它给了我更多的问题。

我将通过展示新的脚本开始:

Update ProjectDates 
SET [Start_Date] = 

(
select right([Start_Date],4) + 
    case 
     when len([Start_Date])=10 then 
      substring([Start_Date],4,2) + left([Start_Date],2) 

     else right('0' + left([Start_Date],firstIndex-1),2) + 
       right('0' + substring([Start_Date],firstIndex+1,secondIndex - firstIndex-1),2) 
       end 

from 
    (
    select mp.[Start_Date], charindex('/',mp.[Start_Date],1) firstIndex, 
      charindex('/',mp.[Start_Date],charindex('/',mp.[Start_Date],1)+1) secondIndex 

    from mbrProject mp 
    join ProjectDates pd 
    on mp.ID = pd.Project_ID 
    )A 

where ProjectDates.Project_ID = mbrProject.ID 
) 

什么情况是,如果我只运行SELECT语句 即摹一切从:

select right([Start_Date],4) 

on mp.ID = pd.Project_ID 
)A 

这工作。

不幸的是,虽然完整的脚本解析正确,它返回以下错误:

Msg 4104, Level 16, State 1, Line 25 
The multi-part identifier "mbrProject.ID" could not be bound. 

任何想法吗?

+0

不能使用CASE这种方式 - 它注定不会被用作流量控制算法。因此,您不能在CASE语句中设置变量,并且您当然不能使用逗号分隔符设置多个变量。 – PinnyM

+0

您应该将日期存储为'DATETIME',而不是字符串。这样做会避免这样的问题。 –

回答

0

试试这个通用的解决方案不同长度的ISO日期格式(yyyymmdd),让您不同的格式。 (假设如果你有10个字符,只有当日期为DD/MM/YYYY),一旦你得到的字符串日期ISO格式转换为日期/日期类型比较。

SQL Fiddle here

--create a table for the demo. 
create table T(mydate varchar(50)) 
insert into T (mydate, details) 
values ('m/d/yyyy'),('mm/d/yyyy'),('m/dd/yyyy'),('dd/mm/yyyy') 


select mydate, 
     right(mydate,4) + case when len(mydate)=10 then 
           substring(mydate,4,2) + left(mydate,2) 
       else right('0' + left(mydate,firstIndex-1),2) + 
     right('0' + substring(mydate,firstIndex+1,secondIndex - firstIndex-1),2) 
         end ISO_format 
from (
select mydate, charindex('/',mydate,1) firstIndex, 
       charindex('/',mydate,charindex('/',mydate,1)+1) secondIndex 
from T) A 

--Results 
MYDATE  ISO_FORMAT 
m/d/yyyy yyyy0m0d 
mm/d/yyyy yyyymm0d 
m/dd/yyyy yyyy0mdd 
dd/mm/yyyy yyyymmdd