2016-11-11 1 views
2

У меня есть таблица с столбцом Days. В столбце Days хранится строка с разделителями-запятыми, представляющая дни недели. Например, значение 1,2 будет представлять Sunday, Monday. Вместо того, чтобы хранить эту информацию в виде строки с разделителями-запятыми, я хочу преобразовать ее в JSON и сохранить ее в столбце Frequency в той же таблице. Например, запись с Days значения 1,2 должна быть обновлена, чтобы сохранить следующее в его Frequency колонка:Обновление столбца базы данных со строкой, построенной на основе значения другого столбца

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

Я нашел способ сделать это с помощью оператора выбора, предполагая, что есть только одна цифра в 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'; 

Однако я не могу показаться, чтобы выяснить, в эффективный способ для обработки преобразования значения, такие как 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 

Хотя, конечно, например. Дни = '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}} 

ОДС при необходимости

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',' ')