2016-11-11 120 views
2

我有一個名爲Days的列表。 Days列存儲代表星期幾的以逗號分隔的字符串。例如,值1,2將代表Sunday, Monday。我不想將此信息存儲爲以逗號分隔的字符串,而是將其轉換爲JSON,並將其存儲在同一個表中名爲Frequency的列中。例如,與1,2Days值的記錄應更新存儲以下在它的Frequency柱:更新數據庫列,並根據另一列的值構建字符串

'{"weekly":"interval":1,"Sunday":true,"Monday":true,"Tuesday":false,"Wednesday":false,"Thursday":false,"Friday":false,"Saturday":false}}' 

我發現了一個辦法做到這一點使用CASE語句,若假設不存在的唯一一個數字Days柱像這樣:

UPDATE SCH_ITM 
SET 
    FREQUENCY = 
     CASE 
     WHEN SCH_ITM.DAYS = 1 THEN '{"weekly":{"interval":1,"Sunday":true,"Monday":false,"Tuesday":false,"Wednesday":false,"Thursday":false,"Friday":false,"Saturday":false}}' 
     WHEN SCH_ITM.DAYS = 2 THEN '{"weekly":{"interval":1,"Sunday":false,"Monday":true,"Tuesday":false,"Wednesday":false,"Thursday":false,"Friday":false,"Saturday":false}}' 
     WHEN SCH_ITM.DAYS = 3 THEN '{"weekly":{"interval":1,"Sunday":false,"Monday":false,"Tuesday":true,"Wednesday":false,"Thursday":false,"Friday":false,"Saturday":false}}' 
     WHEN SCH_ITM.DAYS = 4 THEN '{"weekly":{"interval":1,"Sunday":false,"Monday":false,"Tuesday":false,"Wednesday":true,"Thursday":false,"Friday":false,"Saturday":false}}' 
     WHEN SCH_ITM.DAYS = 5 THEN '{"weekly":{"interval":1,"Sunday":false,"Monday":false,"Tuesday":false,"Wednesday":false,"Thursday":true,"Friday":false,"Saturday":false}}' 
     WHEN SCH_ITM.DAYS = 6 THEN '{"weekly":{"interval":1,"Sunday":false,"Monday":false,"Tuesday":false,"Wednesday":false,"Thursday":false,"Friday":true,"Saturday":false}}' 
     WHEN SCH_ITM.DAYS = 7 THEN '{"weekly":{"interval":1,"Sunday":false,"Monday":false,"Tuesday":false,"Wednesday":false,"Thursday":false,"Friday":false,"Saturday":true}}' 
     END 
WHERE SCH_TYPE = 'W'; 

但是我似乎無法找出一個effecient的方式來處理諸如1,5一個值轉換成正確的JSON表示。顯然我可以寫出所有可能的排列方式,但肯定是更好的方法?

+0

我沒有答案給你,但我想知道爲什麼你不使用DATEPART()並避免列在一起。也許你沒有日期欄,但我只是想知道。 – scsimon

回答

1

好吧,這會給你你要求什麼

create table test (days varchar(20), frequency varchar(500)) 

insert into test(days) values('1'),('2'),('3'),('4'),('5'),('6'),('7'),('1,5') 

update test set frequency = '{"weekly":{"interval":1,' 
    + '"Sunday": ' + case when days like '%1%' then 'true' else 'false' end + ',' 
    + '"Monday": ' + case when days like '%2%' then 'true' else 'false' end + ',' 
    + '"Tuesday": ' + case when days like '%3%' then 'true' else 'false' end + ',' 
    + '"Wednesday": ' + case when days like '%4%' then 'true' else 'false' end + ',' 
    + '"Thursday": ' + case when days like '%5%' then 'true' else 'false' end + ',' 
    + '"Friday": ' + case when days like '%6%' then 'true' else 'false' end + ',' 
    + '"Saturday": ' + case when days like '%7%' then 'true' else 'false' end + '}}' 

select * from test 

儘管當然例如Days ='1234'將產生與'1,2,3,4'相同的結果 - 就這一點而言,'Bl4arg3le12'也是如此。如果Days是一個字符串,你可以把'8'這是沒有意義的?

真的聽起來像你需要額外的表或兩個:

如果「MyTable的」與天列的表,添加天表爲期一週的日子,那麼MyTableDays錶鏈接的MyTable條目到天 - 對於1.5示例,在MyTableDays中將有兩行

1

使用解析功能的幫助和跨應用

;with cteDays As (Select ID,Name From (Values(1,'Sunday'),(2,'Monday'),(3,'Tuesday'),(4,'Wednesday'),(5,'Thursday'),(6,'Friday'),(7,'Saturday')) D(ID,Name)) 

Update YourTable Set Frequency = '{"weekly":"interval":1,'+String+'}}' 
From YourTable A 
Cross Apply (
       Select String = Stuff((Select ','+String 
       From (
        Select String='"'+Name+'":'+case when RetVal is null then 'false' else 'true' end 
        From [dbo].[udf-Str-Parse](A.Days,',') A 
        Right Join cteDays B on RetVal=ID) N 
       For XML Path ('')),1,1,'') 
      ) B 

Select * from YourTable 

更新表

Days Frequency 
1,2  {"weekly":"interval":1,"Sunday":true,"Monday":true,"Tuesday":false,"Wednesday":false,"Thursday":false,"Friday":false,"Saturday":false}} 
1,2,3 {"weekly":"interval":1,"Sunday":true,"Monday":true,"Tuesday":true,"Wednesday":false,"Thursday":false,"Friday":false,"Saturday":false}} 

的UDF如果需要

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10)) 
Returns Table 
As 
Return ( 
    Select RetSeq = Row_Number() over (Order By (Select null)) 
      ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) 
    From (Select x = Cast('<x>'+ Replace(@String,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i) 
); 
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',') 
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ') 
相關問題