[英]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>
要回答您的第一个问题,请使用[ ]
方括号包装这些保留的关键字,而不是将它们作为字符串处理。 就像注释中已经提到的一样,请尝试避免将关键字用于属性。
另外,只要您没有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
如果这是一次性操作,则如何执行都无关紧要。 只要您的结果是正确的,这可能会很慢,很丑且很脏。
您是否在表中有文件路径/名称,或者它们遵循可计算模式? 使用CURSOR
或WHILE
可以很容易地将其循环处理。
您可以使用在问题顶部使用的命令将XML的内容直接加载到变量@xml
并使用SELECT a,b,... INTO #tmpTbl FROM...
在其中写入所有文件的内容。一个进入临时表。
在大多数情况下,最好在循环中将整个语句创建为字符串(不要忘记将所有引号加倍!),然后使用EXEC
执行此操作。 否则您会在OPENROWSET
遇到文件路径的问题...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.