2011-10-12 2 views
2

Я пытаюсь переместить кучу полей из таблицы в xml-блок, содержащийся в одной таблице. После этого я удалю столбец из таблицы. Действительно простая версия (без столбца drop) того, что я придумал, приведен ниже, и это отлично работает в SQL 2008 - однако я обнаружил, что это не сработает на SQL 2005. Я получаю ошибку XQuery: SQL type 'datetime' is not supported in XQuery. I ' м на самом деле делает это посредством исполнения построенного заявления SQL внутри СП из-за количества полей, но для простоты я использовал нормальное заявление в примере:Исправление SQL-обновления с помощью XQuery изменить для работы в SQL 2005

if OBJECT_ID('tempdb..#Case') is not null 
DROP Table #Case; 

CREATE TABLE #Case 
( 
    id INT, 
    DecisionDate DateTime, 
    CaseBlob xml 
) 

INSERT INTO #Case Values(1, '10-OCT-2011 10:10:00', '<CaseBlob></CaseBlob>') 
INSERT INTO #Case Values(2, '20-OCT-2011 10:10:00', '<CaseBlob></CaseBlob>') 
INSERT INTO #Case Values(3, null, '<CaseBlob></CaseBlob>') 
INSERT INTO #Case Values(4, '21-OCT-2011 10:10:00', '<CaseBlob></CaseBlob>') 
INSERT INTO #Case Values(5, null, '<CaseBlob></CaseBlob>') 


UPDATE #Case 
    SET CaseBlob.modify('insert <DecisionDate>{sql:column("#Case.DecisionDate")}</DecisionDate> 
    as last into (/CaseBlob)[1]') 
    WHERE #Case.DecisionDate is not null 
    AND CaseBlob.exist('(/CaseBlob/DecisionDate)') = 0 

SELECT * FROM #CASE 

Я попытался обертывание sql:column("#Case.DecisionDate") с xs:string(sql:column("#Case.DecisionDate")), но это, похоже, не помогает. На @marc_s было указано, что использование sql:column( в операторе .modify(insert не было введено до SQL 2008 - поэтому я считаю, что это красная селедка.

В связи с тем, что это один сценарий миграции, и требуется только один раз запустить, я думаю, что я должен отойти от методов Set и перейти к процедурному циклу, чтобы удовлетворить мои требования. Это похоже на правильный подход из-за ограничения версии сервера и того, что я пытаюсь достичь? Любые указатели очень оценили.

ответ

0

Первая часть:

Вы можете использовать CTE для запроса даты часть преобразуется в строку с использованием временной формат даты 126.

;with C as 
(
    select CaseBlob, 
     convert(varchar(23), DecisionDate, 126) as DecisionDate 
    from #Case 
    where DecisionDate is not null and 
     CaseBlob.exist('(/CaseBlob/DecisionDate)') = 0 
) 
update C 
set CaseBlob.modify('insert <DecisionDate>{sql:column("DecisionDate")}</DecisionDate> 
        as last into (/CaseBlob)[1]') 

Существует маленькая разница в выходе с помощью это по сравнению с вашим оператором обновления. Он будет опускать миллисекунды, если они .000. Если они действительно имеют значение, оно будет включено, чтобы вы не пропускали никаких данных. Это совсем другое.

Вторая часть:

Я не очень понимаю, как это связано с вышеизложенным достаточно хорошо, чтобы дать вам некоторые примеры кода. Но если вам нужно добавить больше материалов из других таблиц, вы можете присоединиться к этим таблицам в CTE и сделать столбцы как выходные данные из CTE, которые будут использоваться в значениях вставки инструкции модификации.

+0

@ Mikeal Eriksson: Спасибо, я попробую - я также удалил вторую несвязанную часть, слишком много продолжающуюся в моей голове в то время. – Tr1stan

+0

Он работал красиво, спасибо. – Tr1stan