Исправление SQL Update с использованием XQuery modify для работы на SQL 2005
Я пытаюсь переместить несколько полей из таблицы в блоб xml, содержащийся в той же таблице. После того, как это успешно, я буду удалять столбец из таблицы. Ниже приведена очень простая версия (без столбца удаления) того, что я придумал, и это прекрасно работает в SQL 2008 - однако я обнаружил, что это не будет работать в SQL 2005. Я получаю ошибку XQuery: SQL type 'datetime' is not supported in XQuery.
На самом деле я делаю это посредством выполнения построенного оператора SQL в SP из-за количества полей, но для простоты я использовал нормальный оператор в примере:
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 и перейти к методу процедурного цикла, чтобы удовлетворить мои требования. Похоже ли это на правильный подход из-за ограничения версии сервера и чего я пытаюсь достичь? Любые указатели очень ценятся.
1 ответ
Первая часть:
Вы можете использовать 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 для использования в операторе изменения, вставляя значения.