Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 XML неисчерпаем...  [new]
aleks2
Guest
Обнаружил, что XML предполагает возможность использовать списки

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="intvalues" type="valuelist"/>

<xs:simpleType name="valuelist">
   <xs:list itemType="xs:integer"/>
</xs:simpleType>

</xs:schema>

 The "intvalues" element in a document could look like this (notice that the list will have five list items):

<intvalues>100 34 56 -23 1567</intvalues>  


А как в MS SQL обратно список -> таблицу?

declare @xml xml = '<intvalues>100 34 56 -23 1567</intvalues>';

select ? -- как его обратно в таблицу?
25 май 16, 15:31    [19218708]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
declare @xml xml = '<intvalues>100 34 56 -23 1567</intvalues>';

select
 b.n.value('.', 'int')
from
 (select cast('<item>' + replace(@xml.value('intvalues[1]', 'varchar(max)'), ' ', '</item><item>') + '</item>' as xml)) a(x) cross apply
 a.x.nodes('item') b(n);
25 май 16, 15:40    [19218770]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4539
aleks2, а так работает?
25 май 16, 15:44    [19218806]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
aleks2
Guest
invm
declare @xml xml = '<intvalues>100 34 56 -23 1567</intvalues>';

select
 b.n.value('.', 'int')
from
 (select cast('<item>' + replace(@xml.value('intvalues[1]', 'varchar(max)'), ' ', '</item><item>') + '</item>' as xml)) a(x) cross apply
 a.x.nodes('item') b(n);


Это очевидное решение, но выглядит чрезмерно сложным и ресурсозатратным.
Неужто в xQuery нема способов прямо разобрать список?
25 май 16, 15:45    [19218813]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
aleks2
Guest
buser
aleks2, а так работает?


Так - работает.
Но как-то очень громоздко выглядит.
25 май 16, 15:51    [19218874]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
aleks2
Неужто в xQuery нема способов прямо разобрать список?
В XQuery есть - fn:tokenize.
Только вот MS SQL XQuery ее нет.
25 май 16, 15:54    [19218898]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
aleks2
Но как-то очень громоздко выглядит.

Как бы тот подход с XML мне кажется разумным компромиссом на каждый день. И пожалуй соглашусь... Но если позволяют условия на SQL Server 2016 все чуточку проще стало:

DECLARE @xml XML = '<intvalues>100 34 56 -23 1567</intvalues>'

SELECT *
FROM STRING_SPLIT(@xml.value('.', 'NVARCHAR(MAX)'), N' ')
25 май 16, 15:59    [19218931]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
aleks2
Guest
aleks2
buser
aleks2, а так работает?


Так - работает.
Но как-то очень громоздко выглядит.


Причем, если чуть углубиться в детали - ваще переливание из пустого в порожнее.

DECLARE @Schema XML
SET @Schema = '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="a">
    <xs:simpleType>
        <xs:list itemType="xs:int" />
    </xs:simpleType>
</xs:element>
</xs:schema>'

CREATE XML SCHEMA COLLECTION exampleschema as @Schema;
GO

DECLARE @XmlDoc AS XML (exampleschema)
SET @XmlDoc = '<a>123 456 789</a>'

select [Xml]=@XmlDoc.query('
    for $i in data(/a) return 
    element temp { $i }
')

select T.ref.value('.', 'int')
from 
(
      select [Xml]=@XmlDoc.query('
            for $i in data(/a) return 
            element temp { $i }
        ')
) A
CROSS APPLY A.Xml.nodes('/temp') T(ref)

DROP XML SCHEMA COLLECTION exampleschema
GO
25 май 16, 16:08    [19218994]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
aleks2, спасибо за последний пример. Просветился идеей :)
25 май 16, 16:14    [19219035]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
Guf
Member

Откуда: Новосибирск
Сообщений: 659
aleks2, не уходи!

Я уже весь форум изрыл вдоль и поперек
https://www.sql.ru/forum/actualsearch.aspx?search=xmlbulkload&sin=0&bid=1&a=&ma=0&dt=-1&s=1&so=1
Я не могу понять как запустить этот балклоад...
Сейчас пользуюсь XQuery, но объемы и сложность входных xml растет в геометрической прогрессии.

Может кто-нибудь кинуть в меня пошаговой инструкцией, для людей с интеллектом чуть ниже срежнего
1. Напиши схему (с этим я справлюсь)
2. возьми вот этот скрипт - вот тут проблема я никак не могу как и что запускать
3. скорми ему схему и xml-файл и узри данные в таблицах!


+ И раз уж пошла такая пьянка

имеет ли смысл использовать bulkload для файлов со структурой типа:
<root>
    <table1>
        <row>
            <col01>1</col01>
           <col02>Иванов</col02>
            <col03>яблоко</col03>
            <col04>3</col04>
        </row>
        <row>
            <col01>2</col01>
            <col02>Петров</col02>
            <col03>груша</col03>
            <col04>7</col04>
        </row>
        <row>
            <col01>3</col01>
            <col02>Сидоров</col02>
            <col03>мандарин</col03>
            <col04>3</col04>
        </row>
    </table1>
    <table2>
        <row>
            <col01>паспортные данные Петрова</col01>
            <col02>35.67</col02>
            <col03>уровень доходов Петрова</col03>
            <col04>яблоко</col04>
        </row>
        <row>
            <col01>паспортные данные Иванова</col01>
            <col02>77</col02>
            <col03>уровень доходов Иванова</col03>
            <col04>груша</col04>
        </row>
        <row>
            <col01>паспортные данные Сидорова</col01>
            <col02>3.3</col02>
            <col03>уровень доходов Сидорова</col03>
            <col04>персик</col04>
        </row>
    </table2>
    </root>

И т.д., много таблиц с разной структурой
но в каждой есть 2-3 колонки (с разными названиями), но нужными данными
в итоге нужно получить таблицу вида
строкацифра
яблоко3
груша7
мандарин3
яблоко35.67
груша77
персик3.3

первые три строки из table1 - col03 и col04
последние три строки из table2 - col04 и col02

Или ну его нафиг, и дальше пользовать многокилометровые портянки на XQuery?
25 май 16, 17:39    [19219481]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
aleks2
Guest
2. Самое простое. Многократно приведен в примерах MS.
Dim objBL 
Set objBL = CreateObject("SQLXMLBulkLoad.SQLXMLBulkload.4.0")
objBL.ConnectionString = "provider=SQLOLEDB;data source=DC3\WSUS;database=tempdb;integrated security=SSPI"
objBL.ErrorLogFile = "error.log"

objBL.SchemaGen = True
objBL.SGDropTables = True

objBL.Execute "directionlist_Schema.xsd ", "directionlist.xml"
Set objBL = Nothing


Если хочешь - приведу PowerShell-скрипт.

1. Это самое сложное. Попервости.
25 май 16, 18:44    [19219703]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
Guf
Member

Откуда: Новосибирск
Сообщений: 659
aleks2,

Да, приведи, пожалуйста.
И как насчёт того, то в спойлере? Есть резон заморачиваться?
Сейчас пока работает, но очень не стабильно, медленно и гомоздко. Как только появится время обязательно попробую.

Спасибо

Сообщение было отредактировано: 25 май 16, 21:06
25 май 16, 19:46    [19219862]     Ответить | Цитировать Сообщить модератору
 Re: XML неисчерпаем...  [new]
aleks2
Guest
То, что под спойлером грузится на раз. Там тривиально все.

Да, sqlXmlBulkLoad - это сильно быстрее xQuery.

Но схемы писать - надо учиться.

К сообщению приложен файл (alean.ps1 - 7Kb) cкачать
26 май 16, 06:05    [19220873]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить