#tsql #xml-parsing #sql-server-2008-r2
#tsql #синтаксический анализ XML #sql-server-2008-r2
Вопрос:
Я работаю в SQL Server 2008 R2. У меня около 20 баз данных с одинаковой структурой. Я не совсем уверен, где я ошибся в своем коде. Если бы кто-нибудь мог указать на мою ошибку или указать мне на несколько ресурсов по этому вопросу, это было бы оценено.
Код, который я запускаю, является:
create table #temp
([Client] varchar(100), [Language_Code] char(100))
exec sp_msforeachdb '
if ''?'' like ''%'' and exists(select * from ?.sys.tables t where t.name = ''LicenceInfoes'')
begin
DECLARE @MyXML XML
Declare @lang_code char(100)
set @lang_code = ''(SELECT a.b.value''(''Laguages[1]'',''char(100)'')'' FROM @MyXML.nodes(''Licence'') a(b))''
insert into #temp select ''?'', @lang_code
end
'
select * from #temp
drop table #temp
Конечным результатом является эта ошибка:
Сообщение 102, уровень 15, состояние 1, строка 7
Неправильный синтаксис рядом с ‘Laguages [1]’.
Желаемым результатом будет таблица с 2 столбцами, подобными этому:
<DB_Name> <Language_Codes>
Name1 en-GB, en-US
Исходный запрос отлично работает при самостоятельном выполнении и предоставляет мне данные, которые я ищу, но я хотел бы запустить его сразу для всех баз данных, чтобы сэкономить мне время и обеспечить автоматизацию процесса.
DECLARE @MyXML XML
SET @MyXML = (select LicenceData from LicenceInfoes where Id='1001')
SELECT
a.b.value('Laguages[1]', 'char(100)') AS Language_Codes
FROM
@MyXML.nodes('Licence') a(b)
и образец XML, хранящийся в одной из баз данных
<Licence xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Clients />
<LastUpdated>2014-06-03T15:59:46.9831585Z</LastUpdated>
<CustomerId>9999999</CustomerId>
<CustomerName>xxxxx</CustomerName>
<ContactEmail>someone@somewhere.com</ContactEmail>
<Type>Commercial</Type>
<Languages>
<Language>en-GB</Language>
<Language>en-US</Language>
</Languages>
<DefaultLanguagePack>en-GB</DefaultLanguagePack>
Любая помощь здесь приветствуется.
Редактировать
Попробовав несколько вещей, я обнаружил, где находится ошибка.
Ошибка находится в переменной @myXML:
SET @MyXML = ''(select LicenceData from t.LicenceInfoes)''
Изменение t.LicenceInfoes на ?..LicenceInfoes исправил проблему, с которой я столкнулся.
Ответ №1:
Помогает ли это?
DECLARE @Tbl TABLE (ID INT NOT NULL, XmlContent XML)
INSERT INTO @tbl VALUES(1, '<Licence xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Clients />
<LastUpdated>2014-06-03T15:59:46.9831585Z</LastUpdated>
<CustomerId>9999999</CustomerId>
<CustomerName>xxxxx</CustomerName>
<ContactEmail>someone@somewhere.com</ContactEmail>
<Type>Commercial</Type>
<Languages>
<Language>en-GB</Language>
<Language>en-US</Language>
</Languages>
<DefaultLanguagePack>en-GB</DefaultLanguagePack></Licence>')
SELECT
ID,
XT.XC.value('(.)[1]', 'varchar(50)')
FROM
@Tbl
CROSS APPLY
XmlContent.nodes('/Licence/Languages/Language') AS XT(XC)
Это приводит к выводу:
ID (No column name)
1 en-GB
1 en-US
Комментарии:
1. это прекрасно работает как есть. Мне нужно выполнить поиск этих данных, которые хранятся в столбце таблицы LicenceInfoes. Я попытался добавить оператор select, заменяющий данные xml, и я получаю пустую таблицу в качестве вывода. XML имеет одинаковую структуру для всех баз данных, но может отличаться по мере добавления или удаления языков.
Ответ №2:
Я полагаю, что ваша ошибка возникает из-за неправильного написания Laguages[1]
в строке 7. Измените его на Languages[1]
, и он должен выдать правильный вывод.
Комментарии:
1. образец XML был автоматически скорректирован в соответствии с отображаемым. он должен читать <Лаги> .
Ответ №3:
Я думаю, это может помочь.
exec sp_msforeachdb '
if ''?'' like ''%'' and exists(select * from ?.sys.tables t where t.name = ''LicenceInfoes'')
begin
DECLARE @MyXML XML
Declare @lang_code char(100)
SET @MyXML = (select LicenceData from t.LicenceInfoes)
set @lang_code = (SELECT a.b.value(''Laguages[1]'',''char(100)'') FROM @MyXML.nodes(''Licence'') a(b))
insert into #temp select ''?'', @lang_code
end'
Я не понимаю значения if ''?'' like ''%''
, но теперь запрос синтаксически корректен.
Комментарии:
1. Я попробовал, и вот результат: Col1: DB_Name Col2: (ВЫБЕРИТЕ значение a.b.(‘Laguages[1]’,’char(100)’) ИЗ @myXML.nodes(‘Лицензия’) a(b))
2. @user3753561, я не вижу результата, но я обновил сообщение.
Ответ №4:
Попробовав несколько ваших вариантов, я получил следующую ошибку:
Msg 208, Level 16, State 1, Line 7
Invalid object name 'LicenceInfoes'.
Я понял, что допустил ошибку в той части кода, где я установил переменную @myXML.
это было:
SET @MyXML = (select LicenceData from LicenceInfoes)
добавление «? ..» перед именем таблицы исправило это.
SET @MyXML = (select LicenceData from ?..LicenceInfoes)
В итоге я обновил свой код благодаря marc_s. Теперь это выглядит так:
create table Tbl (Client varchar(max), Language_Code varchar(max))
exec sp_msforeachdb '
if ''?'' like ''%'' and exists(select * from ?.sys.tables t where t.name = ''LicenceInfoes'')
begin
SET QUOTED_IDENTIFIER ON
INSERT INTO Tbl
SELECT
''?'',
a.b.value(''(.)[1]'',''varchar(100)'') AS Language_Codes
FROM ?..LicenceInfoes
cross apply LicenceData.nodes(''/Licence/Laguages/Language'') a(b)
end'
select * from Tbl
drop table Tbl
Результат этого точно такой же, как у marc_s в его примере, и это то, что я хотел.
Спасибо всем за ответы и помощь!