Sql server 将xml写入DB、T-SQL的存储过程
我试图编写一个存储过程,将xml写入DB,T-SQL 下面是我的示例xml(在prod环境中,它将有大量的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,程
):
我使用实体框架来调用存储过程。调用刚刚发生(没有错误),但数据库没有更新。我很确定我在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;