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

Откуда:
Сообщений: 30
Здравствуйте.

Столкнулся с следующей проблемой. При выполнении самостоятельно написанной процедуры генерации xml-кода в MS SQL Server Management Studio результат корректный (в приложенном скриншоте слева). Если же я точно так же запускаю процедуру в других средах, например DBForge Studio, то результат формируется "по частям" (в приложенном скриншоте справа). Из-за этого искажается полученный Xml-код, т.к. в нем появляются разделительные символы, которые рушат структуру. Подскажите пожалуйста в чем причина и можно ли от этого избавиться.

Заранее благодарен.

К сообщению приложен файл. Размер - 103Kb
8 авг 17, 23:00    [20709608]     Ответить | Цитировать Сообщить модератору
 Re: Разный результат формирования xml в разных средах разработки  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36979
Обратиться к разработчикам других сред.
8 авг 17, 23:29    [20709644]     Ответить | Цитировать Сообщить модератору
 Re: Разный результат формирования xml в разных средах разработки  [new]
env
Member

Откуда: Россия, Москва
Сообщений: 6041
UncleFedor32,

Скрины, мягко говоря, ни о чём.
Пальцем в небо, предположу, что у DbForge есть настройка навроде lob fetch chunk, которая влияет на получение результата при фетче. Либо это на уровне используемого данной IDE драйвера для доступа к SQL Server.

Ну и было бы неплохо привести пример на основе вашей процедуры генерации XML, который был бы воспроизводим на другом окружении.
9 авг 17, 09:05    [20709874]     Ответить | Цитировать Сообщить модератору
 Re: Разный результат формирования xml в разных средах разработки  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
У Вас хранимка возращяет идентичный результат в обоих случаях? Если да, то все равно где она выполняется. Хоть в консоле, хоть в SSMS, хоть в dbForge.

Последний к слову использует дата ридер на базовом уровне такой же как и SSMS. При условии того что не включена пажинация. А то что на скрине справа у Вас не показывается в некоторых строках XML - это не говорит о том, что он неккоретно вычитывается. Просто это фишка такая - если XML большой, то показывать вместо него картинку и не нагружать контрол. Если кликаете на строку, то потом данные в отдельном окне можно просмотреть.
9 авг 17, 09:26    [20709909]     Ответить | Цитировать Сообщить модератору
 Re: Разный результат формирования xml в разных средах разработки  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
И еще есть одна не сильно приятная бажина с SQL Server при генерации XML. TYPE используете?

SELECT x = (
    SELECT [@obj_id] = o.[object_id]
         , [@obj_name] = o.[name]
         , [@sch_name] = s.[name]
         , (
             SELECT i.[name]
                  , i.column_id
                  , i.user_type_id
                  , i.is_nullable
                  , i.is_identity
             FROM sys.all_columns i
             WHERE i.[object_id] = o.[object_id]
             FOR XML AUTO, TYPE
         )
    FROM sys.all_objects o
    JOIN sys.schemas s ON o.[schema_id] = s.[schema_id]
    WHERE o.[type] IN ('U', 'V')
    FOR XML PATH('obj'), ROOT('objs'), TYPE -- !!!
)

SELECT x = CAST((
    SELECT [@obj_id] = o.[object_id]
         , [@obj_name] = o.[name]
         , [@sch_name] = s.[name]
         , (
             SELECT i.[name]
                  , i.column_id
                  , i.user_type_id
                  , i.is_nullable
                  , i.is_identity
             FROM sys.all_columns i
             WHERE i.[object_id] = o.[object_id]
             FOR XML AUTO, TYPE
         )
    FROM sys.all_objects o
    JOIN sys.schemas s ON o.[schema_id] = s.[schema_id]
    WHERE o.[type] IN ('U', 'V')
    FOR XML PATH('obj'), ROOT('objs') -- !!!
) AS XML)  -- !!!

Если да, то попробуйте вариант второй который приведен
9 авг 17, 09:31    [20709917]     Ответить | Цитировать Сообщить модератору
 Re: Разный результат формирования xml в разных средах разработки  [new]
UncleFedor32
Member

Откуда:
Сообщений: 30
AlanDenton, спасибо большое за ответ. Да, type использую. Попробую Ваше предложение. О результате напишу)
9 авг 17, 11:13    [20710234]     Ответить | Цитировать Сообщить модератору
 Re: Разный результат формирования xml в разных средах разработки  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
UncleFedor32, там ситуация с TYPE весьма странная. Могу даже репро дать.

Вначале генерим один и тот же XML с разными опциями:

/*
    EXEC sys.sp_configure 'show advanced options', 1
    GO
    RECONFIGURE
    GO

    EXEC sys.sp_configure 'xp_cmdshell', 1
    GO
    RECONFIGURE WITH OVERRIDE
    GO
*/

USE AdventureWorks2014
GO

DROP TABLE IF EXISTS tempdb.dbo.xml_file_1
DROP TABLE IF EXISTS tempdb.dbo.xml_file_2
GO

SELECT x = (
    SELECT [@obj_id] = o.[object_id]
         , [@obj_name] = o.[name]
         , [@sch_name] = s.[name]
         , (
             SELECT i.[name]
                  , i.column_id
                  , i.user_type_id
                  , i.is_nullable
                  , i.is_identity
             FROM sys.all_columns i
             WHERE i.[object_id] = o.[object_id]
             FOR XML AUTO, TYPE
         )
    FROM sys.all_objects o
    JOIN sys.schemas s ON o.[schema_id] = s.[schema_id]
    WHERE o.[type] IN ('U', 'V')
    FOR XML PATH('obj'), ROOT('objs'), TYPE -- !!!
)
INTO tempdb.dbo.xml_file_1

SELECT x = CAST((
    SELECT [@obj_id] = o.[object_id]
         , [@obj_name] = o.[name]
         , [@sch_name] = s.[name]
         , (
             SELECT i.[name]
                  , i.column_id
                  , i.user_type_id
                  , i.is_nullable
                  , i.is_identity
             FROM sys.all_columns i
             WHERE i.[object_id] = o.[object_id]
             FOR XML AUTO, TYPE
         )
    FROM sys.all_objects o
    JOIN sys.schemas s ON o.[schema_id] = s.[schema_id]
    WHERE o.[type] IN ('U', 'V')
    FOR XML PATH('obj'), ROOT('objs') -- !!!
) AS XML)  -- !!!
INTO tempdb.dbo.xml_file_2

DECLARE @sql NVARCHAR(4000) = 'bcp "SELECT * FROM tempdb.dbo.xml_file_1" queryout "X:\sample_1.xml" -S ' + @@servername + ' -T -w -r -t'
EXEC sys.xp_cmdshell @sql

SET @sql = 'bcp "SELECT * FROM tempdb.dbo.xml_file_2" queryout "X:\sample_2.xml" -S ' + @@servername + ' -T -w -r -t'
EXEC sys.xp_cmdshell @sql

/*
    <objs>
      <obj obj_id="2098106515" obj_name="SalesTerritoryHistory" sch_name="Sales">
        <i name="BusinessEntityID" column_id="1" user_type_id="56" is_nullable="0" is_identity="0" />
        <i name="TerritoryID" column_id="2" user_type_id="56" is_nullable="0" is_identity="0" />
        <i name="StartDate" column_id="3" user_type_id="61" is_nullable="0" is_identity="0" />
        <i name="EndDate" column_id="4" user_type_id="61" is_nullable="1" is_identity="0" />
        <i name="ModifiedDate" column_id="6" user_type_id="61" is_nullable="0" is_identity="0" />
      </obj>
    </objs>
*/

и после видим что они реально различаются (хотя при просмотре на глаз одинаковы):

SET NOCOUNT ON

USE tempdb
GO

SELECT x
     , xml_size = DATALENGTH(x)
     , string_size = DATALENGTH(CAST(x AS NVARCHAR(MAX)))
     , sha1 = HASHBYTES('SHA1', CAST(x AS NVARCHAR(MAX)))
FROM dbo.xml_file_1

UNION ALL

SELECT x
     , DATALENGTH(x)
     , DATALENGTH(CAST(x AS NVARCHAR(MAX)))
     , HASHBYTES('SHA1', CAST(x AS NVARCHAR(MAX)))
FROM dbo.xml_file_2

SELECT DATALENGTH(CAST(BulkColumn AS XML))
FROM OPENROWSET(BULK 'X:\sample_1.xml', SINGLE_BLOB) x

UNION ALL

SELECT DATALENGTH(CAST(BulkColumn AS XML))
FROM OPENROWSET(BULK 'X:\sample_2.xml', SINGLE_BLOB) x

SELECT *
FROM sys.columns
WHERE [object_id] IN (OBJECT_ID('dbo.xml_file_1'), OBJECT_ID('dbo.xml_file_2'))

SELECT [type_desc], total_pages, used_pages, data_pages
FROM sys.allocation_units a
WHERE EXISTS(
        SELECT *
        FROM sys.partitions p
        WHERE p.[object_id] IN (OBJECT_ID('dbo.xml_file_1'), OBJECT_ID('dbo.xml_file_2'))
            AND p.[partition_id] = a.container_id
    )

------------------------------------------------------

SET STATISTICS PROFILE, TIME, IO ON

SELECT t.c.value('@obj_name', 'SYSNAME')
     , t2.c2.value('@name', 'SYSNAME')
FROM dbo.xml_file_1
OUTER APPLY x.nodes('objs/obj') t(c)
CROSS APPLY t.c.nodes('i') t2(c2)

SELECT t.c.value('@obj_name', 'SYSNAME')
     , t2.c2.value('@name', 'SYSNAME')
FROM dbo.xml_file_2
OUTER APPLY x.nodes('objs/obj') t(c)
CROSS APPLY t.c.nodes('i') t2(c2)

SET STATISTICS PROFILE, TIME, IO OFF

/*
    Table 'xml_file_1'. Scan count 1, logical reads 1, ..., lob logical reads 729990, ..., lob read-ahead reads 17400.
       CPU time = 28015 ms, elapsed time = 28311 ms

    Table 'xml_file_2'. Scan count 1, logical reads 1, ..., lob logical reads 818, ..., lob read-ahead reads 0.
       CPU time = 235 ms, elapsed time = 386 ms
*/

Итого за счет TYPE в некоторых сценариях XML получается хреновенький и парсинг его получается адской мукой раскаленным железом.
9 авг 17, 11:54    [20710345]     Ответить | Цитировать Сообщить модератору
 Re: Разный результат формирования xml в разных средах разработки  [new]
UncleFedor32
Member

Откуда:
Сообщений: 30
AlanDenton, помогло решение через cast ((...) a xml), причем от type я оставил (решил попробовать) и сработало.

спасибо большое за помощь и развернутые пояснения)
9 авг 17, 19:06    [20711807]     Ответить | Цитировать Сообщить модератору
 Re: Разный результат формирования xml в разных средах разработки  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Рад, что помогло. Увы такую вот "фичу" майкрософт чинить не будет. Она с 2005 версии насколько я помню появилась в одном из сервис-паков. Потому и приходится весьма внимательно следить за тем как данные сохраняются. У меня такое было, что в таблице часть данных была нормальная, а часть через TYPE. В итоге полдня убил на то чтобы понять - почему разное время парсинга на примерно одинаковых данных.

Относительно dbForge я бы разработчикам все таки ссылку на данный топик скинул. Репро для них тем более, что есть.
9 авг 17, 20:26    [20711922]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить