Хранимая процедура, которая записывает xml в БД, T- SQL - PullRequest
0 голосов
/ 11 февраля 2020

Я пытаюсь написать хранимую процедуру, которая записывает xml в БД, T- SQL.

Вот мой пример xml (который будет иметь значительное число <RECORD> s в среде prod):

<?xml version="1.0" encoding="windows-1251"?>
<DATA FORMAT_VERSION="1.0">
    <RECORD>
        <NAME>МІЖНАРОДНА ГРОМАДСЬКА ОРГАНІЗАЦІЯ МІЖНАРОДНА АКАДЕМІЯ БІОЕНЕРГОТЕХНОЛОГІЙ</NAME>
        <SHORT_NAME>МАБЕТ</SHORT_NAME>
        <EDRPOU>00011601</EDRPOU>
        <ADDRESS>01001, м.Київ, Шевченківський район, ВУЛИЦЯ ПРОРІЗНА, будинок 8, офіс 426</ADDRESS>
        <STAN>зареєстровано</STAN>
    </RECORD>
</DATA>

Я передаю путь к файлу xml в параметре @pathToXml.

Вот моя хранимая процедура:

CREATE PROCEDURE [dbo].[LegalContractorsDataSynchronize] 
(
    @pathToXml varchar
)
AS
BEGIN

BEGIN TRANSACTION

DELETE FROM [dbo].[LegalContractors];

INSERT INTO [dbo].[LegalContractors]([Code], [ShortName], [Name], [LegalAddress], [Status])
SELECT CONVERT([Code], [ShortName], [Name], [LegalAddress], [Status])
FROM OPENROWSET(BULK, @pathToXml, SINGLE_CLOB) as x

COMMIT TRANSACTION

END

Я использую Entity Framework для вызова хранимой процедуры. Вызов просто происходит (без ошибок), но БД не обновляется. Я очень уверен, что что-то неправильно набрал в выражении INSERT. Я следовал этому примеру.

Может ли кто-нибудь указать, как можно заполнить три столбца в моей БД, используя данные из соответствующих элементов в xml? Столбцы Code, ShortName, Name, LegalAddress и Status.

enter image description here

ОБНОВЛЕНИЕ

После публикации ответа я попробовал предлагаемое решение. Я получаю сообщение об ошибке:

Сообщение 102, Уровень 15, Состояние 1, Процедура LegalContractorsDataSynchronize, Строка 15 [Batch Start Line 0] Неверный синтаксис рядом с'@pathToXml'.

Вот мой код:

CREATE PROCEDURE [dbo].[LegalContractorsDataSynchronize] 
(
    @pathToXml varchar
)
AS
BEGIN

BEGIN TRANSACTION

DELETE FROM [dbo].[LegalContractors];

;WITH XmlFile (xmlData) AS
(
   SELECT TRY_CAST(BulkColumn AS XML) 
   FROM OPENROWSET(BULK @pathToXml, SINGLE_BLOB) AS x
)
INSERT INTO [dbo].[LegalContractors] ([Code], [ShortName], [Name], [LegalAddress], [Status])
SELECT c.value('(EDRPOU/text())[1]','NVARCHAR(100)') AS [Code]
   , c.value('(SHORT_NAME/text())[1]','NVARCHAR(512)') AS [ShortName]
    , c.value('(NAME/text())[1]','NVARCHAR(2048)') AS [Name]
   , c.value('(ADDRESS/text())[1]','NVARCHAR(2048)') AS [LegalAddress]
   , c.value('(STAN/text())[1]','NVARCHAR(100)') AS [Status]
FROM XmlFile CROSS APPLY xmlData.nodes('/DATA/RECORD') AS t(c);

COMMIT TRANSACTION

END

enter image description here

1 Ответ

1 голос
/ 11 февраля 2020

Пожалуйста, попробуйте следующее. Насколько мне известно, OPENROWSET () не принимает параметр имени файла в качестве переменной.

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (
   ID INT IDENTITY PRIMARY KEY,
   Code NVARCHAR(50) NOT NULL,
   ShortName NVARCHAR(100) NOT NULL,
   [Name] NVARCHAR(100) NOT NULL,
   LegalAddress NVARCHAR(100) NOT NULL,
   [Status] NVARCHAR(50) NOT NULL
);
-- DDL and sample data population, end

-- Method #1
-- XML file is hardcoded
;WITH XmlFile (xmlData) AS
(
    SELECT TRY_CAST(BulkColumn AS XML) 
    FROM OPENROWSET(BULK 'c:\...\Ukraine.xml', /*CODEPAGE = '65001',*/ SINGLE_BLOB) AS x
)
INSERT INTO @tbl (Code, ShortName, [Name], LegalAddress, [Status])
SELECT c.value('(EDRPOU/text())[1]','NVARCHAR(50)') AS [Code]
   , c.value('(SHORT_NAME/text())[1]','NVARCHAR(100)') AS [ShortName]
    , c.value('(NAME/text())[1]','NVARCHAR(100)') AS [Name]
   , c.value('(ADDRESS/text())[1]','NVARCHAR(100)') AS [LegalAddress]
   , c.value('(STAN/text())[1]','NVARCHAR(50)') AS [Status]
FROM XmlFile CROSS APPLY xmlData.nodes('/DATA/RECORD') AS t(c);

-- test
SELECT * FROM @tbl;

-- Method #2
-- dynamic XML file name as a parameter
DECLARE @xml XML
   , @sql NVARCHAR(MAX)
   , @fileName VARCHAR(256) = 'c:\...\Ukraine.xml';

SET @sql = N'SELECT @xmlOut = XmlDoc FROM OPENROWSET (BULK ' + QUOTENAME(@fileName,NCHAR(39)) + ', SINGLE_BLOB) AS Tab(XmlDoc)';

EXEC master.sys.sp_executesql @sql, N'@xmlOut XML OUTPUT', @xmlOut = @xml OUTPUT;

INSERT INTO @tbl (Code, ShortName, [Name], LegalAddress, [Status])
SELECT c.value('(EDRPOU/text())[1]','NVARCHAR(50)') AS [Code]
   , c.value('(SHORT_NAME/text())[1]','NVARCHAR(100)') AS [ShortName]
    , c.value('(NAME/text())[1]','NVARCHAR(100)') AS [Name]
   , c.value('(ADDRESS/text())[1]','NVARCHAR(100)') AS [LegalAddress]
   , c.value('(STAN/text())[1]','NVARCHAR(50)') AS [Status]
FROM @xml.nodes('/DATA/RECORD') AS t(c);

-- test
SELECT * FROM @tbl;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...