为什么在尝试将XML文档(下面的文件示例)读入SQL Server时会获得NULL值?我认为它是由于阅读文件。 SQL的第一部分似乎没问题 - 我在SQLSERVER网格中看到了xml文件。但不知道,如何读取数据。想法是 - 我想将XML文件导入SQL SERVER,使用简单的SQL查询进行一些数据清理,然后将其导入到其他系统中。
此XML使用DTD。
感谢您的帮助。
SELECT CONVERT(XML, BulkColumn,2) AS BulkColumn
FROM OPENROWSET(BULK 'H:\file.xml', SINGLE_BLOB) AS x;
DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
SELECT @XML = XMLData FROM XMLwithOpenXML WHERE ID = '1' -- The row to process
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
SELECT *
FROM OPENXML(@hDoc, '/BMECAT/HEADER/CATALOG/',1)
WITH
(
language nvarchar(max)
)
EXEC sp_xml_removedocument @hDoc
GO
<!-- Generated by crossbase mediasolution GmbH (http://www.crossbase.de) -->
<BMECAT xmlns="http://www.bmecat.org/bmecat/1.2/bmecat_new_catalog" version="1.2">
<HEADER>
<CATALOG>
<LANGUAGE>DE</LANGUAGE>
<CATALOG_ID>ML103</CATALOG_ID>
<CATALOG_VERSION>1</CATALOG_VERSION>
<DATETIME type="generation_date">
<DATE>2015-10-12</DATE>
<TIME>07:10:42</TIME>
<TIMEZONE>+02:00</TIMEZONE>
</DATETIME>
</CATALOG>
<BUYER>
<ADDRESS type="buyer" />
</BUYER>
<SUPPLIER>
<SUPPLIER_NAME>GmbH</SUPPLIER_NAME>
<ADDRESS type="supplier">
<NAME>GmbH</NAME>
<NAME2>fabrik</NAME2>
<STREET>e 1</STREET>
<ZIP>6973</ZIP>
<CITY>st</CITY>
<COUNTRY>eich</COUNTRY>
<PHONE>05-0</PHONE>
<FAX>705-44</FAX>
<EMAIL>info@com</EMAIL>
<URL>www.com</URL>
</ADDRESS>
</SUPPLIER>
答案 0 :(得分:1)
原始文件的Thx。我把它装下来,可以毫无问题地阅读:试试这样:
DECLARE @yourXML AS XML=
(
SELECT CONVERT(XML, BulkColumn,2) AS BulkColumn
FROM OPENROWSET(BULK 'H:\file.xml', SINGLE_BLOB) AS x
);
--simple approach
WITH XMLNAMESPACES(DEFAULT 'http://www.bmecat.org/bmecat/1.2/bmecat_new_catalog')
SELECT @YourXML.value('(/BMECAT/HEADER/CATALOG/LANGUAGE)[1]','varchar(2)');
--with OPENXML
DECLARE @hDoc INT;
EXEC sp_xml_preparedocument @hDoc output, @YourXML,'<root xmlns:dflt="http://www.bmecat.org/bmecat/1.2/bmecat_new_catalog" />';
SELECT LANGUAGE
FROM OPENXML(@hDoc,'/dflt:BMECAT/dflt:HEADER/dflt:CATALOG')
WITH(LANGUAGE VARCHAR(MAX) 'dflt:LANGUAGE');
EXEC sp_xml_removedocument @hDoc
GO
在您找到一堆XML示例(包含或不包含名称空间)后,您可以比较并找到所需的最佳方法。只需将其粘贴到一个空的查询窗口中并执行:
DECLARE @xmlNaked XML='<root><element test="SomeValue"/></root>';
DECLARE @xmlNamespace XML='<root xmlns="http://testNS" xmlns:ns2="http://testNS/ns2"><element test="SomeValue"/><ns2:namespaced test2="another value"/></root>';
--Normale approach
SELECT @xmlNaked.value('(/root/element/@test)[1]','varchar(max)') AS TheElement;
--No return value due to namespace
SELECT @xmlNamespace.value('(/root/element/@test)[1]','varchar(max)') AS TheElementMissing
,@xmlNamespace.value('(/root/namespaced/@test2)[1]','varchar(max)') AS NamespacedMissing;
--Declaring default namespace before (xmlns is the default, ns2 additional)
WITH XMLNAMESPACES(DEFAULT 'http://testNS')
SELECT @xmlNamespace.value('(/root/element/@test)[1]','varchar(max)') AS TheElement
,@xmlNamespace.value('(/root/namespaced/@test2)[1]','varchar(max)') AS NamespacedMissing;
--Declaring default namespace and additional namespace
WITH XMLNAMESPACES('http://testNS/ns2' AS ns2, DEFAULT 'http://testNS')
SELECT @xmlNamespace.value('(/root/element/@test)[1]','varchar(max)') AS TheElement
,@xmlNamespace.value('(/root/ns2:namespaced/@test2)[1]','varchar(max)') AS NamespacedMissing;
--now with OPENXML, namespaces must be introduced in sp_xml_preparedocument
DECLARE @i INT, @ns VARCHAR(100);
EXEC sp_xml_preparedocument @i output, @xmlNaked;
SELECT test AS TheElement FROM OPENXML(@i,'/root/element',2) WITH(test VARCHAR(MAX) '@test')
--not return value due to namespace
EXEC sp_xml_preparedocument @i output, @xmlNamespace;
SELECT test AS TheElementMissing FROM OPENXML(@i,'/root/element',2) WITH(test VARCHAR(MAX) '@test')
--There's AFAIK no "direct" declaration of the default namespace possible. Look at the declaration of "dflt" namespace
EXEC sp_xml_preparedocument @i output, @xmlNamespace,'<root xmlns:dflt="http://testNS" />';
SELECT test AS TheElement FROM OPENXML(@i,'/dflt:root/dflt:element') WITH(test VARCHAR(MAX))
--Now the full thing
EXEC sp_xml_preparedocument @i output, @xmlNamespace,'<root xmlns:dflt="http://testNS" xmlns:ns2="http://testNS/ns2"/>';
SELECT test AS TheElement,test2 AS Namespace
FROM OPENXML(@i,'/dflt:root',2)
WITH (test VARCHAR(MAX) 'dflt:element/@test'
,test2 VARCHAR(MAX) 'ns2:namespaced/@test2' )
答案 1 :(得分:1)
是的,您的示例有效。两种方法。但现在我尝试直接从文件中读取。什么都没发生 - NULL就像以前一样返回。我做错了什么?:
SELECT CONVERT(XML, BulkColumn,2) AS BulkColumn
FROM OPENROWSET(BULK 'H:\file.xml', SINGLE_BLOB) AS x;
DECLARE @yourXML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
SELECT @yourXML = XMLData FROM XMLwithOpenXML WHERE ID = '1' -- The row to process
EXEC sp_xml_preparedocument @hDoc OUTPUT, @yourXML
--with OPENXML
DECLARE @i INT;
EXEC sp_xml_preparedocument @i output, @YourXML,'<root xmlns:dflt="http://www.bmecat.org/bmecat/1.2/bmecat_new_catalog" />';
SELECT LANGUAGE
FROM OPENXML(@i,'/dflt:BMECAT/dflt:HEADER/dflt:CATALOG') WITH(LANGUAGE VARCHAR(MAX) 'dflt:LANGUAGE');
EXEC sp_xml_removedocument @hDoc
GO