私のソリューションを修正してXMLデータをSQL Serverテーブルにインポートする作業を手伝ってくれる人はいますか?私は研究をしましたが、この仕事は達成するのが非常に困難でした。私が見つけたものはすべて単純なデータで機能しましたが、私の名前と値は「website_details」セクションで別々になっています。これが私のスクリプトが機能していない理由です。約200のXMLファイルがあり、それぞれにインポートするレコードが1,000を超えるため、構造を変更できません。私が使用しているデータは機密情報と見なされるため、値の名前と値を変更して、これを投稿できるようにしました。
Websitesテーブルの最初の挿入コマンドは完全に機能し、すべてのデータをインポートします。私が抱えている問題は、2番目の挿入コマンドにあります。 @ xmlData.nodes定義は、問題があると私が思うところです。 "website_details"セクションでは、他の情報とは異なり、名前と値が分かれているため、構造を定義するのに苦労しています。
現時点で私のデータベースの概要を説明するために、2つのテーブルで構成されています。それらはwebsitesおよびwebsite_detailsです。 Web_ID列は両方のテーブルに含まれており、website_detailsをWebサイトに接続する外部キーです。私はwebsite_viewというデータを結合するために使用しているビューも持っています。
これは私のXMLファイルから抜粋したサンプルデータです:
<WEBSITES>
<WEBSITE>
<WEBSITE_ID>sta001</WEBSITE_ID>
<WEBSITE_ALTERNATE_ID/>
<WEBSITE_VERSION>4</WEBSITE_VERSION>
<TYPE>DYNAMIC</TYPE>
<NAME>TEST WEBSITE</NAME>
<WEBSITE_DETAILS>
<WEBSITE_DETAIL>
<NAME>COST</NAME>
<VALUE>500</VALUE>
<INHERITED>false</INHERITED>
</WEBSITE_DETAIL>
<WEBSITE_DETAIL>
<NAME>LANGUAGE</NAME>
<VALUE>EN</VALUE>
<INHERITED>false</INHERITED>
</WEBSITE_DETAIL>
<WEBSITE_DETAIL>
<NAME>DATABASE</NAME>
<VALUE/>
<INHERITED>false</INHERITED>
</WEBSITE_DETAIL>
</WEBSITE_DETAILS>
</WEBSITE>
<WEBSITE>
<WEBSITE_ID>mmn023</WEBSITE_ID>
<WEBSITE_ALTERNATE_ID/>
<WEBSITE_VERSION>3</WEBSITE_VERSION>
<TYPE>DYNAMIC</TYPE>
<NAME>TEST WEBSITE 2</NAME>
<WEBSITE_DETAILS>
<WEBSITE_DETAIL>
<NAME>COST</NAME>
<VALUE>750</VALUE>
<INHERITED>false</INHERITED>
</WEBSITE_DETAIL>
<WEBSITE_DETAIL>
<NAME>LANGUAGE</NAME>
<VALUE>RU</VALUE>
<INHERITED>false</INHERITED>
</WEBSITE_DETAIL>
<WEBSITE_DETAIL>
<NAME>DATABASE</NAME>
<VALUE>TRUE</VALUE>
<INHERITED>false</INHERITED>
</WEBSITE_DETAIL>
</WEBSITE_DETAILS>
</WEBSITE>
</WEBSITES>
これは私が使用しているストアドプロシージャです:
USE [websitesDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_website_import] (
@xmlData XML ,
@retValue varchar(100) OUTPUT
)
AS
BEGIN
SET @retValue='Failed';
INSERT INTO [websites](
[Web_ID],
[Web_Version],
[Web_Type],
[Web_Name]
)
SELECT
[Table].[Column].value('WEBSITE_ID [1]', 'nvarchar(100)'),
[Table].[Column].value('WEBSITE_VERSION [1]', 'nvarchar(100)'),
[Table].[Column].value('TYPE [1]', 'nvarchar(100)'),
[Table].[Column].value('NAME [1]', 'nvarchar(100)')
FROM @xmlData.nodes('/ WEBSITES / WEBSITE') as [Table]([Column])
IF(@@ROWCOUNT > 0 )
SET @retValue='SUCCESS';
INSERT INTO [website_details](
[Web_ID],
[cost],
[language],
[database]
)
SELECT
[Table].[Column].value('WEBSITE_ID [1]', 'nvarchar(100)'),
[Table].[Column].value('COST [1]', 'nvarchar(100)'),
[Table].[Column].value('LANGUAGE [1]', 'nvarchar(100)'),
[Table].[Column].value('DATABASE [1]', 'nvarchar(100)')
FROM @xmlData.nodes('/ WEBSITES / WEBSITE / WEBSITE_DETAILS') as [Table]([Column])
IF(@@ROWCOUNT > 0 )
SET @retValue='SUCCESS'
;
/WEBSITES/WEBSITE
を2番目のクエリでも使用し、values句のNAME
ノードに対して述語を使用して、VALUE
ノードから値を取得します。
select S.X.value('(WEBSITE_ID/text())[1]', 'nvarchar(100)') as WEBSITE_ID,
S.X.value('(WEBSITE_DETAILS/WEBSITE_DETAIL[(NAME/text())[1] eq "COST"]/VALUE/text())[1]', 'nvarchar(100)'),
S.X.value('(WEBSITE_DETAILS/WEBSITE_DETAIL[(NAME/text())[1] eq "LANGUAGE"]/VALUE/text())[1]', 'nvarchar(100)'),
S.X.value('(WEBSITE_DETAILS/WEBSITE_DETAIL[(NAME/text())[1] eq "DATABASE"]/VALUE/text())[1]', 'nvarchar(100)')
from @xmlData.nodes('/WEBSITES/WEBSITE') as S(X)
結果:
sta001 500 EN NULL
mmn023 750 RU TRUE
ネクロマンシング。
誰かがそれをファイルおよび変数なしにする必要がある場合(テーブル値関数に適しています):
SELECT
--myTempTable.XmlCol.value('.', 'varchar(36)') AS val
myTempTable.XmlCol.query('./ID').value('.', 'varchar(36)') AS ID
,myTempTable.XmlCol.query('./Name').value('.', 'nvarchar(MAX)') AS Name
,myTempTable.XmlCol.query('./RFC').value('.', 'nvarchar(MAX)') AS RFC
,myTempTable.XmlCol.query('./Text').value('.', 'nvarchar(MAX)') AS Text
,myTempTable.XmlCol.query('./Desc').value('.', 'nvarchar(MAX)') AS Description
--,myTempTable.XmlCol.value('(Desc)[1]', 'nvarchar(MAX)') AS DescMeth2
FROM
(
SELECT
CAST('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data-set>
<record>
<ID>1</ID>
<Name>A</Name>
<RFC>RFC 1035[1]</RFC>
<Text>Address record</Text>
<Desc>Returns a 32-bit IPv4 address, most commonly used to map hostnames to an IP address of the Host, but it is also used for DNSBLs, storing subnet masks in RFC 1101, etc.</Desc>
</record>
<record>
<ID>2</ID>
<Name>NS</Name>
<RFC>RFC 1035[1]</RFC>
<Text>Name server record</Text>
<Desc>Delegates a DNS zone to use the given authoritative name servers</Desc>
</record>
</data-set>
' AS xml) AS RawXml
) AS b
--CROSS APPLY b.RawXml.nodes('//record/ID') myTempTable(XmlCol);
CROSS APPLY b.RawXml.nodes('//record') myTempTable(XmlCol);
またはファイルから直接(テーブル値関数)
SELECT
--myTempTable.XmlCol.value('.', 'varchar(36)') AS val
myTempTable.XmlCol.query('./ID').value('.', 'varchar(36)') AS ID
,myTempTable.XmlCol.query('./Name').value('.', 'nvarchar(MAX)') AS Name
,myTempTable.XmlCol.query('./RFC').value('.', 'nvarchar(MAX)') AS RFC
,myTempTable.XmlCol.query('./Text').value('.', 'nvarchar(MAX)') AS Text
,myTempTable.XmlCol.query('./Desc').value('.', 'nvarchar(MAX)') AS Description
FROM
(
SELECT CONVERT(XML, BulkColumn) AS RawXml
FROM OPENROWSET(BULK 'D:\username\Desktop\MyData.xml', SINGLE_BLOB) AS RowSetName
) AS b
CROSS APPLY b.RawXml.nodes('//record') myTempTable(XmlCol)
例えば.
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tfu_RPT_SEL_XmlData]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[tfu_RPT_SEL_XmlData]
GO
CREATE FUNCTION [dbo].[tfu_RPT_SEL_XmlData]
(
@in_language varchar(10)
,@in_reportingDate datetime
)
RETURNS TABLE
AS
RETURN
(
SELECT
--myTempTable.XmlCol.value('.', 'varchar(36)') AS val
myTempTable.XmlCol.query('./ID').value('.', 'varchar(36)') AS ID
,myTempTable.XmlCol.query('./Name').value('.', 'nvarchar(MAX)') AS Name
,myTempTable.XmlCol.query('./RFC').value('.', 'nvarchar(MAX)') AS RFC
,myTempTable.XmlCol.query('./Text').value('.', 'nvarchar(MAX)') AS Text
,myTempTable.XmlCol.query('./Desc').value('.', 'nvarchar(MAX)') AS Description
FROM
(
SELECT CONVERT(XML, BulkColumn) AS RawXml
FROM OPENROWSET(BULK 'D:\username\Desktop\MyData.xml', SINGLE_BLOB) AS RowSetName
) AS b
CROSS APPLY b.RawXml.nodes('//record') myTempTable(XmlCol)
)
GO
SELECT * FROM tfu_RPT_SEL_XmlData('DE', CURRENT_TIMESTAMP)