C# 针对Microsoft SQL Server,将日期和时间一次性组合到暂存表中的大量xml文件的日期时间中
这方面我是新手,所以请容忍我。我已经成功地获取了数百个xml文档,并通过一个查询将它们放入一个暂存表中。查看我的数据,我意识到如果我的action date和action time列合并到一个列中,我将调用datetime,其中包含datetime数据类型。考虑到我想一次完成这一切,我该如何完成?我正在使用Microsoft SQL Server 2016 这是我的问题C# 针对Microsoft SQL Server,将日期和时间一次性组合到暂存表中的大量xml文件的日期时间中,c#,sql-server,xml,datetime,C#,Sql Server,Xml,Datetime,这方面我是新手,所以请容忍我。我已经成功地获取了数百个xml文档,并通过一个查询将它们放入一个暂存表中。查看我的数据,我意识到如果我的action date和action time列合并到一个列中,我将调用datetime,其中包含datetime数据类型。考虑到我想一次完成这一切,我该如何完成?我正在使用Microsoft SQL Server 2016 这是我的问题 CREATE TABLE [dbo].[staagingTable] ( [Counter] INT NOT NULL
CREATE TABLE [dbo].[staagingTable]
(
[Counter] INT NOT NULL,
[majority] [nvarchar](max) NULL,
[congress] [int] NULL,
[session] [nvarchar](max) NULL,
[chamber] [nvarchar](max) NULL,
[rollcall-num] [int] NULL,
[legis-num] [nvarchar](max) NULL,
[vote-question] [nvarchar](max) NULL,
[vote-type] [nvarchar](max) NULL,
[vote-result] [nvarchar](max) NULL,
[action-date] [nvarchar](max) NULL,
[action-time] [nvarchar](max) NULL,
[vote-desc] [nvarchar](max) NULL,
[sourceXML] [XML] NULL
);
GO
DECLARE @Counter INT=1;
DECLARE @command VARCHAR(MAX);
WHILE @Counter<800
BEGIN
SET @command=
'
DECLARE @xmlString VARCHAR(MAX)=
(
SELECT BulkColumn
FROM OPENROWSET (BULK ''C:\Users\Owner\Documents\congress\House votes\114 congress 2015\Passage\roll' + REPLACE(STR(@Counter,3),' ','0') + '.xml'', SINGLE_BLOB) AS c
);
SET @xmlString=SUBSTRING(@xmlString,CHARINDEX(''<rollcall-vote>'',@xmlString,1),9999999);
DECLARE @xml XML=CAST(@xmlString AS XML);
INSERT INTO dbo.staagingTable(Counter, majority, congress,[session], chamber, [rollcall-num], [legis-num], [vote-question], [vote-type], [vote-result], [action-date], [action-time], [vote-desc], [sourceXML])
SELECT
' + CAST(@Counter AS VARCHAR(10)) + ',
v.value(N''majority[1]'', N''nvarchar(max)''),
v.value(N''congress[1]'', N''int''),
v.value(N''session[1]'', N''nvarchar(max)''),
v.value(N''chamber[1]'', N''nvarchar(max)''),
v.value(N''rollcall-num[1]'', N''int''),
v.value(N''legis-num[1]'', N''nvarchar(max)''),
v.value(N''vote-question[1]'', N''nvarchar(max)''),
v.value(N''vote-type[1]'', N''nvarchar(max)''),
v.value(N''vote-result[1]'', N''nvarchar(max)''),
v.value(N''action-date[1]'', N''nvarchar(max)''),
v.value(N''action-time[1]'', N''nvarchar(max)''),
v.value(N''vote-desc[1]'', N''nvarchar(max)''),
@xml
FROM
@xml.nodes(N''/rollcall-vote/vote-metadata'') AS A(v);
';
BEGIN TRY
EXEC(@command);
END TRY
BEGIN CATCH
PRINT ERROR_MESSAGE()
END CATCH;
SET @Counter = @Counter + 1;
END
SELECT * FROM dbo.staagingTable;
GO
DROP TABLE dbo.staagingTable;
这是我的查询生成的表的屏幕截图。我想合并成一列的两列上面都画有紫色符号
这是我的一个xml文档的婴儿版
<rollcall-vote>
<vote-metadata>
<majority>R</majority>
<congress>114</congress>
<session>1st</session>
<chamber>U.S. House of Representatives</chamber>
<rollcall-num>6</rollcall-num>
<legis-num>H RES 5</legis-num>
<vote-question>On Agreeing to the Resolution</vote-question>
<vote-type>YEA-AND-NAY</vote-type>
<vote-result>Passed</vote-result>
<action-date>6-Jan-2015</action-date>
<action-time time-etz="17:30">5:30 PM</action-time>
<vote-desc>Adopting rules for the One Hundred Fourteenth Congress</vote-desc>
</vote-metadata>
</rollcall-vote>
更新
根据Cam Bruce的建议,我在下面的屏幕截图中进行了更改,其中也包含了相应的错误
尝试2
尝试3
尝试4
企图
这一尝试利用了Shnugo的建议。这两列已合并,但它们似乎是来自虚拟值的列,而不是我的表
尝试2
尝试3
在[dbo].[staagingTable]中创建日期时间字段 并修改该新字段的插入查询,并用
CONVERTdatetime、'action-date[1]+''+action-time[1],100假设日期和时间字符串的格式与屏幕截图中的格式相同,您可以使用xquery concat函数将它们连接起来:
v.value(N''concat(action-date[1], concat('''' '''', action-time[1]))'', N''nvarchar(max)''),
如果我理解正确,那么从XML到暂存表的所有读取过程都已成功完成。现在你想把这两列合并成一个类型化的DATETIME好主意 顺便说一句:对于你的下一个问题:尽量避免张贴无关的代码 不幸的是,使用的格式是非常糟糕的文化和语言依赖!而且是 试着这样做:
SET LANGUAGE ENGLISH;
--Some dummy values for testing
DECLARE @Dummy TABLE([action-date] NVARCHAR(MAX),[action-time] NVARCHAR(MAX));
INSERT INTO @Dummy VALUES
('6-Jan-2015','5:30 PM')
,('8-Jan-2015','2:10 PM')
,('22-Jan-2015','11:04 AM')
,('10-Mar-2015','00:00 AM');
--The existing [action-date] can be converted with code "106". In order to allow
--the usage of your time format I first combine them on string level and then
--re-convert them to `DATETIME` using format "100"
SELECT CONVERT(DATETIME,CONVERT(VARCHAR(12),CONVERT(DATETIME,d.[action-date],106),100)+ ' ' + d.[action-time],100)
FROM @Dummy AS d
结果
2015-01-06 17:30:00.000
2015-01-08 14:10:00.000
2015-01-22 11:04:00.000
2015-03-10 00:00:00.000
更新如何在项目中使用此选项
阅读完成后,完成并准备好所有以前的XML数据,现在都在表dbo.staagingTable中
尝试这样做,首先添加一个新列,然后使用“我的代码”设置其值
有一个最终选择来检查结果。很简单
ALTER TABLE [dbo].[staagingTable] ADD CombinedDate DATETIME NULL;
GO
SET LANGUAGE ENGLISH;
UPDATE [dbo].[staagingTable]
SET CombinedDate=CONVERT(DATETIME,CONVERT(VARCHAR(12),CONVERT(DATETIME,[action-date],106),100)+ ' ' + [action-time],100);
SELECT [action-date],[action-time],CombinedDate
FROM [dbo].[staagingTable];
GO
DROP TABLE dbo.staagingTable
如果没有using xquery value函数(请参阅我的最新更新)这是行不通的。我很确定我没有正确地应用您的建议。concat函数是xquery的函数,因此它需要位于xquery表达式中的文字引号内,在这里引用操作时间[1],等等。因此它需要是一个长字符串文字:“concataction date[1],concat,action time[1]我已经拍摄了第二次尝试的截图。我很难理解你正在使用的一些短语。就像我说的,我是个新手。如果我能有更全面的插图和你的解释,它可以帮助我理解你在说什么。你几乎做到了,看起来像是复制粘贴错误。基本上,当您调用v.valueexpression、datatype时,即计算一个xquery表达式并将其转换为指定的sql数据类型,该类型通常只是属性名称,例如action time[1],但在本例中,我们也使用多个concat函数来获取所需的值。我尝试了您的建议。你可以在我的编辑中看到它。在未来,我将尝试只包含我认为人们需要帮助我的代码。如果他们要求,我总是可以添加更多的代码。@anang不,你完全错了!我的意思是:像以前一样将数据读入staging表。现在,您可以将上面的代码用于staagingTable的列。表格@Dummy仅用于创建一个独立的工作示例。。。你根本不需要这个!我已经发布了我的下一次尝试。执行此操作时,我收到一个错误,指出combineddate是无效的列名。我觉得这很奇怪。ALTER TABLE行没有添加该列吗?还有,人们是如何将数据读入他们的暂存表的?您的代码应该1创建一个语句来读取一个xml文件,2执行它,3反复执行,4在循环结束后添加DateCombined列并更新其值。您在尝试3中所做的是在插入任何行之前添加列并运行UPDATE命令…@Shnugo Ok。让我一步一步地试一下。读取一个xml文件的语句是什么样子的?你的指示让我感到很失落。对不起,你真的是认真的吗?在你最后的问题中,我花了几个小时来帮助你解决这个问题!您已经成功地阅读了XML。在现有代码的末尾有SELECT*FROM dbo.staagingTable;我假设你在这里看到了你的数据。对的您的问题与xml无关,也与C无关,发布的代码也没有任何关联!您的问题是,在导入一些“我的暂存表包含此数据”后,请在此处添加“复制”可粘贴数据。如何将动作和数据结合起来
e和操作时间设置为正确的日期时间值?抱歉。我问的是真的。你使用的术语我不熟悉。我没有接受过sql方面的任何正式培训。我以前从未编程过。我是个新手,但现在我的生活状况要求我建立这个数据库。我醒着的时候都花在这个项目上。我需要知道查询应该是什么样子。这是我唯一可以学习的方法。这是我能把你展示给我的东西应用到我未来工作中的唯一方法。现在我所做的就是在黑暗中拍摄。