【发布时间】:2020-06-25 22:21:12
【问题描述】:
我正在使用的源数据,这些都在一个名为 body 的列中。遗憾的是,该数据无法更改。数据通过来自我们网络外部的电子邮件进入,然后进入 Email2DB。 Email2DB 是一个将电子邮件数据放入表格的应用程序。
这不是数据通常存储在我们的表中的方式,这是一个临时的东西,用于在用户电脑离线时记录问题,以便跟踪问题的数量。
身体
21/05/2020| 16:01| Pathe 2.0 Delay| Pathe| LRW10| terence
出于报告目的,我将数据拆分为单独的列。
我需要将单独的日期和时间作为 DateTime 格式放在一列中。
例如:2020-05-21 16:01
我正在尝试将数据输入到以下临时表中,但对于我的一生,我无法将日期和时间转换为 DateTime。
DECLARE @QuickData TABLE (TicketDate datetime, Issue varchar(50), Category varchar(50), ComputerName varchar(30), UserName varchar(50));
如果我将临时表 TicketDate 更改为 TicketDate varchar(25),则数据正常。但是最终目标是能够传入 @DateFrom 和 @DateTo 并能够在 @DateFrom 和 @DateTo 之间执行 where TicketDate ,除非 TicketDate 是日期时间格式,否则我不能这样做。
我无法理解的是,即使我将数据插入到带有 Ticket 为 Varchar 的临时表中,结果如下所示
Result if insert TicketDate as Varchar
一个数据在临时表中,我尝试使用 cast as datetime 和 cast as datetime2 运行 select 语句,还尝试转换为 datetime,但没有任何效果,我总是遇到同样的错误
从字符串转换日期和/或时间时转换失败。
如果有人能解决,我将在下面添加我尝试过的尝试之一,我将不胜感激。
请知道我已经用谷歌搜索了无数的想法并尝试了多种日期时间格式。
DECLARE @dateFrom DateTime = '2020-05-21 08:00:00'
DECLARE @dateTo DateTime = '2020-05-25 17:30:00'
DECLARE @QuickData TABLE (TicketDate varchar(25), Issue varchar(50), Category varchar(50), ComputerName varchar(30), UserName varchar(50));
INSERT INTO @QuickData
SELECT CONVERT(VARCHAR(25), (TRIM(CONVERT(VARCHAR(10), CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) + dbo.f_SplitString(body,2,'|') + ':00'),120),
dbo.f_SplitString(body,3,'|') as 'Issue', dbo.f_SplitString(body,4,'|') as 'Category',
dbo.f_SplitString(body,5,'|') as 'PCName', dbo.f_SplitString(body,6,'|') as 'User' FROM t_Quick;
SELECT convert(datetime,TicketDate) as 'TicketDate' , Issue, Category, ComputerName, UserName
FROM @QuickData
WHERE TicketDate between @dateFrom and @dateTo
ORDER BY TicketDate DESC;
使用的拆分字符串函数如下。
USE [Central]
GO
/****** Object: UserDefinedFunction [dbo].[f_SplitString] Script Date: 26/06/2020 00:07:31 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
ALTER FUNCTION [dbo].[f_SplitString]
(
@multiwordstring VARCHAR(255),
@wordnumber integer,
@delimiter char(1)
)
returns VARCHAR(255)
AS
BEGIN
DECLARE @remainingstring VARCHAR(255)
SET @remainingstring=@multiwordstring
DECLARE @numberofwords NUMERIC
SET @numberofwords=(LEN(@remainingstring) - LEN(REPLACE(@remainingstring, @delimiter, '')) + 1)
DECLARE @word VARCHAR(50)
DECLARE @parsedwords TABLE
(
line NUMERIC IDENTITY(1, 1),
word VARCHAR(255)
)
WHILE @numberofwords > 1
BEGIN
SET @word=LEFT(@remainingstring, CHARINDEX(@delimiter, @remainingstring) - 1)
INSERT INTO @parsedwords(word)
SELECT @word
SET @remainingstring= REPLACE(@remainingstring, @word + @delimiter, '')
SET @numberofwords=(LEN(@remainingstring) - LEN(REPLACE(@remainingstring, @delimiter, '')) + 1)
IF @numberofwords = 1
BREAK
ELSE
CONTINUE
END
IF @numberofwords = 1
SELECT @word = @remainingstring
INSERT INTO @parsedwords(word)
SELECT @word
RETURN
(SELECT RTrim(LTrim(word))
FROM @parsedwords
WHERE line = @wordnumber)
END
【问题讨论】:
-
所以这个
21/05/2020| 16:01| Pathe 2.0 Delay| Pathe| LRW10| terence是一栏?我认为您需要以更好、更规范的格式将数据推回并获取到您的数据库中。现在它不是数据库,而是文本文件。 -
您是否真的尝试将查询解构为单个块以查看失败的位置?在我的简单测试中(我没有你对
f_SplitString函数的实现)它可以工作。运行这个:SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)), CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) + dbo.f_SplitString(body,2,'|')。如果失败,请继续从最后删除代码块,直到找出问题所在。 -
@AaronBertrand 数据通过电子邮件从不在我们网络中的外部来源传入,然后通过 Email2DB。此应用程序将其放入表中,但无法将其分成不同的列,因此为什么我要处理这么糟糕的数据。
-
This 20-year old thing 除了将整个数据集转储到单个列中之外,什么也做不了?也许是时候研究不同的软件了。
-
基于您的文本字符串中有空格的事实,我怀疑您的字符串拆分功能正在修剪,因此您在日期和小时组件之间失去了一个空格,因此我要求您 de - 构建您的查询以找到问题。
标签: sql-server datetime