繁体   English   中英

将数据从XML文档传输到SQL Server时,有两个问题:with子句中出现错误以及对日期时间的担忧

[英]Two questions in transferring data from an XML document to SQL Server: an error emerging in the with clause and a concern about datetime

我是新来的,所以请忍受我。 我正在使用SQL Server,并试图将数据从XML文档传输到SQL Server。

我有两个问题。

问题1:我在“哪里”有一个错误。 如果我完全删除了where行,则错误将移至“会话”。

问题2:我希望适当命名的datetime列具有datetime数据类型。 当我查看xml文档时,虽然看到日期时间等于T。 我相信这个T象征着时间。 我担心这个T会引起问题,因为我从未见过SQL Server中的数据类型datetime在日期和时间的中间有一个字母。 这有可能吗? 如果是这样,我该怎么办? 我假设如果出现问题,我将不得不更改我的数据类型(如果发生问题,应该将其更改为什么?)。 更改xml文档本身以删除T不是一个选择。

这是我的查询的复制粘贴:

DECLARE @x xml

SELECT @x = p
FROM OPENROWSET 
    (BULK 'C:\Users\Owner\Documents\congress\House votes\114 congress 2015\Passage\705.xml; , SINGLE_BLOB) AS HouseVote705(p)

DECLARE @hdoc int

EXEC sp_xml_prepare document @hdoc OUTPUT, @x

SELECT *
FROM OPENXML (@hdoc, '/roll', 1)
WITH (
'where' char,
'session' tinyint,
'year' smallint,
roll smallint,
'datetime' datetime)
EXEC sp_xml_removedocument

这是我的xml文档的复制粘贴:

<roll where="house" session="114" datetime="2015-12-18T09:49:00-05:00"> </roll>

我的查询和我正在使用的xml文档的屏幕截图。

要回答您的第一个问题,请使用[ ]方括号包装这些保留的关键字,而不是将它们作为字符串处理。 就像注释中已经提到的一样,请尝试避免将关键字用于属性。

另外,只要您没有XSD(xml模式定义),就尝试尽可能少地解释类型。 [where]绝对不是单个字符。 并且您确定该会话将始终适合于TINYINT吗?

对于第二个问题,提供的datetime为Iso8601格式。 只需将其读取为varchar,然后进行转换即可。

以下是基于您的屏幕截图的示例:

DECLARE @x XML

SELECT  @x = CAST(N'<roll where="house" session="114" year="2015" roll="705" source="house.gov" datetime="2015-12-18T09:49:00-05:00" updated="2016-12-25T10:03:32-05:00"/>' AS XML)

DECLARE @hdoc INT

EXEC sp_xml_preparedocument @hdoc OUTPUT, @x, '<roll xmlns:xyz="urn:MyNamespace"/>'; 

SELECT [where] AS DocWhere
, [session] AS DocSession
, [year] AS DocYear
, roll
, CONVERT(datetime2, [datetime], 126) AS DocDatetime
FROM OPENXML (@hdoc, '/roll', 1) 
WITH (
   [where] VARCHAR(MAX)
 , [session] INT
 , [year] INT
 , [roll] INT
 , [datetime] VARCHAR(30)
 )

就像您的其他问题一样: FROM OPENXML已过时,不应再使用(存在罕见的例外)...

为此,请使用现代XML方法

DECLARE @xml XML=
N'<roll where="house" session="114" datetime="2015-12-18T09:49:00-05:00"> </roll>';

SELECT @xml.value(N'(/roll/@where)[1]',N'nvarchar(max)') AS roll_where
      ,@xml.value(N'(/roll/@session)[1]',N'int') AS roll_session
      ,@xml.value(N'(/roll/@datetime)[1]',N'datetime') AS roll_datetime

结果

roll_where  roll_session    roll_datetime
house       114             2015-12-18 14:49:00.000

更新数百个文件 ...

如果这是一次性操作,则如何执行都无关紧要。 只要您的结果是正确的,这可能会很慢,很丑且很脏。

您是否在表中有文件路径/名称,或者它们遵循可计算模式? 使用CURSORWHILE可以很容易地将其循环处理。

您可以使用在问题顶部使用的命令将XML的内容直接加载到变量@xml并使用SELECT a,b,... INTO #tmpTbl FROM...在其中写入所有文件的内容。一个进入临时表。

在大多数情况下,最好在循环中将整个语句创建为字符串(不要忘记将所有引号加倍!),然后使用EXEC执行此操作。 否则您会在OPENROWSET遇到文件路径的问题...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM