Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 将xml写入DB、T-SQL的存储过程_Sql Server_Xml_Tsql_Stored Procedures - Fatal编程技术网

Sql server 将xml写入DB、T-SQL的存储过程

Sql server 将xml写入DB、T-SQL的存储过程,sql-server,xml,tsql,stored-procedures,Sql Server,Xml,Tsql,Stored Procedures,我试图编写一个存储过程,将xml写入DB,T-SQL 下面是我的示例xml(在prod环境中,它将有大量的): 我使用实体框架来调用存储过程。调用刚刚发生(没有错误),但数据库没有更新。我很确定我在INSERT语句中输入了错误的内容。我仿效了这个例子 有人能指出我如何使用xml中各个元素的数据填充数据库中的三列吗?这些列是code、ShortName、Name、LegalAddress和Status 更新 答案公布后,我尝试了建议的解决方案。我得到一个错误: Msg 102,15级,状态1,程

我试图编写一个存储过程,将xml写入DB,T-SQL

下面是我的示例xml(在prod环境中,它将有大量的
):

我使用实体框架来调用存储过程。调用刚刚发生(没有错误),但数据库没有更新。我很确定我在
INSERT
语句中输入了错误的内容。我仿效了这个例子

有人能指出我如何使用xml中各个元素的数据填充数据库中的三列吗?这些列是
code
ShortName
Name
LegalAddress
Status

更新

答案公布后,我尝试了建议的解决方案。我得到一个错误:

Msg 102,15级,状态1,程序LegalContractorsDataSynchronize,第15行[批处理起始行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

请尝试以下操作。据我所知,OPENROWSET()不接受file name参数作为变量

SQL


我更新了我的问题。您能帮我解决我遇到的问题吗?正如我前面所说的“…OPENROWSET()不接受文件名参数作为变量…”。我更新了答案。我相信你错了。
OPENROWSET
不支持文件名:
'data_file'是要将其数据复制到目标表中的数据文件的完整路径。
@hellouworld:它支持文本文件名,而不是变量。语法明确地这么说(
'data\u file'
,而不是
@string\u variable |'data\u file'
)。语句必须动态生成。Jeroen,请在LinkedIn上与我联系。
我正在使用实体框架调用存储过程。
那你为什么要使用这个存储过程呢?只需创建适当的DbContext和实体,并使用EF插入数据。现在,在服务器上尝试immitate EF时,只会给调用增加开销。如果您真的需要这个存储过程,一个简单的ADO.NET SqlCommand会更好。您还可以将数据作为XML类型的参数传递,声明不带长度的
VARCHAR
为。如果您打算在其中填充路径,则更是如此。@PanagiotisKanavos,xml大小大于1Gb。如果我们考虑到应用程序和数据库位于不同的服务器上,这是不可行的(以我手头的基础设施容量)。xml存储在db服务器端。
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
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
-- 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;