Sql server
另一种方法是创建如下表值函数,该函数按顺序返回字符串拆分:Sql server ,sql-server,datetime,Sql Server,Datetime,另一种方法是创建如下表值函数,该函数按顺序返回字符串拆分: CREATE FUNCTION dbo.fnOrderedStringSplit ( @List varchar(4000), @Delimiter char(1) ) RETURNS TABLE AS RETURN ( SELECT Element = ROW_NUMBER() OVER (ORDER BY [Number]), [Value]
CREATE FUNCTION dbo.fnOrderedStringSplit
(
@List varchar(4000),
@Delimiter char(1)
)
RETURNS TABLE
AS
RETURN
(
SELECT Element = ROW_NUMBER() OVER (ORDER BY [Number]),
[Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number],
CHARINDEX(@Delimiter, @List + @Delimiter, [Number]
) - [Number])))
FROM (SELECT TOP (4000) ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_columns) AS x ([Number])
WHERE SUBSTRING(@Delimiter + @List, [Number], 1) = @Delimiter
AND Number <= LEN(@List)
);
解决方案
字符串拆分函数会修剪字符串,因此会丢失日期和时间组件之间的空间
更改代码
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~(2),'f'分裂字符串< /代码>
给人一条鱼,你可以喂他一天;教人钓鱼,你可以喂他一辈子 您可以通过如下方式解构查询,轻松地自行调试:SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105) FROM t_Quick
SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) FROM t_Quick
SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) + dbo.f_SplitString(body,2,'|') FROM t_Quick
您可以查看每个阶段的输出,以了解问题所在。解决方案
字符串拆分函数会修剪字符串,因此会丢失日期和时间组件之间的空间
更改代码
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~(2),'f'分裂字符串< /代码>
给人一条鱼,你可以喂他一天;教人钓鱼,你可以喂他一辈子 您可以通过如下方式解构查询,轻松地自行调试:SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105) FROM t_Quick
SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) FROM t_Quick
SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) + dbo.f_SplitString(body,2,'|') FROM t_Quick
您可以查看每个阶段的输出,以了解问题所在。谢谢大家的建议。不过,我终于解决了这个问题。当转换时间时,存在一个“非普通”空间,该空间无法通过修剪移除,因此解决方案使用了子字符串,效果非常好
DECLARE @QuickData TABLE (TicketDate datetime, Issue varchar(50), Category varchar(50), ComputerName varchar(30), UserName varchar(50));
INSERT INTO @QuickData
SELECT convert(datetime, try_CONVERT(VARCHAR(25), (TRIM(CONVERT(VARCHAR(10), CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) + ' ' + substring(dbo.f_SplitString(body,2,'|'),2,5) + ':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 * from @QuickData
where TicketDate between @dateFrom and @dateTo
order by 1 desc;
谢谢大家的建议。不过,我终于解决了这个问题。当转换时间时,存在一个“非普通”空间,该空间无法通过修剪移除,因此解决方案使用了子字符串,效果非常好
DECLARE @QuickData TABLE (TicketDate datetime, Issue varchar(50), Category varchar(50), ComputerName varchar(30), UserName varchar(50));
INSERT INTO @QuickData
SELECT convert(datetime, try_CONVERT(VARCHAR(25), (TRIM(CONVERT(VARCHAR(10), CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) + ' ' + substring(dbo.f_SplitString(body,2,'|'),2,5) + ':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 * from @QuickData
where TicketDate between @dateFrom and @dateTo
order by 1 desc;
那么这个
21/05/2020 | 16:01 | Pathe 2.0 Delay | Pathe | LRW10 | terence
是一列吗?我认为您需要向后推,以更好、更规范的格式将数据输入数据库。现在它不是一个数据库,而是一个文本文件。你是否真的尝试过将你的查询分解成单独的块来查看它失败的地方?在我的简单测试中(我没有实现f_SplitString
函数),它可以工作。运行以下命令:选择CONVERT(date,dbo.f_拆分字符串(body,1','|'),105),CONVERT(date,dbo.f_拆分字符串(body,1','|'),105),23),CONVERT(date,dbo.f_拆分字符串(body,1','|'),105),23))+dbo.f_拆分字符串(body,2','。如果失败,请继续从末尾删除代码块,直到您找到问题的实际位置。@AaronBertrand数据是通过电子邮件从外部来源(不在我们的网络中)传入的,然后通过Email2DB。这个应用程序将其放入表中,但无法将其分为不同的列,因此我不得不处理如此糟糕的数据。除了将整个数据集转储到单个列中之外,无法执行任何操作?也许是时候研究一下不同的软件了。基于您的文本字符串中有空格的事实,我怀疑您的字符串拆分函数正在进行修剪,因此您在日期和小时组件之间失去了一个空格,因此,我要求您对查询进行解构以找到问题。那么这21/05/2020 | 16:01 | Pathe 2.0 Delay | Pathe | LRW10 | terence
是一列吗?我认为您需要向后推,以更好、更规范的格式将数据输入数据库。现在它不是一个数据库,而是一个文本文件。你是否真的尝试过将你的查询分解成单独的块来查看它失败的地方?在我的简单测试中(我没有实现f_SplitString
函数),它可以工作。运行以下命令:选择CONVERT(date,dbo.f_拆分字符串(body,1','|'),105),CONVERT(date,dbo.f_拆分字符串(body,1','|'),105),23),CONVERT(date,dbo.f_拆分字符串(body,1','|'),105),23))+dbo.f_拆分字符串(body,2','。如果失败,请继续从末尾删除代码块,直到您找到问题的实际位置。@AaronBertrand数据是通过电子邮件从外部来源(不在我们的网络中)传入的,然后通过Email2DB。这个应用程序将其放入表中,但无法将其分为不同的列,因此我不得不处理如此糟糕的数据。除了将整个数据集转储到单个列中之外,无法执行任何操作?也许是时候研究一下不同的软件了。基于您的文本字符串中有空格的事实,我怀疑您的字符串拆分函数正在进行修剪,因此您在日期和小时组件之间失去了一个空格,因此,我要求您对查询进行解构,以找到问题所在。使用字符串concatBetter datetime使用字符串concatBetter datetime
SELECT CONVERT(VARCHAR(25), (TRIM(CONVERT(VARCHAR(10), CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23))
+ dbo.f_SplitString(body,2,'|') + ':00'),120),
SELECT CONVERT(VARCHAR(25), (TRIM(CONVERT(VARCHAR(10), CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23))
+ ' ' + dbo.f_SplitString(body,2,'|') + ':00'),120),
SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105) FROM t_Quick
SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) FROM t_Quick
SELECT CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) + dbo.f_SplitString(body,2,'|') FROM t_Quick
DECLARE @QuickData TABLE (TicketDate datetime, Issue varchar(50), Category varchar(50), ComputerName varchar(30), UserName varchar(50));
INSERT INTO @QuickData
SELECT convert(datetime, try_CONVERT(VARCHAR(25), (TRIM(CONVERT(VARCHAR(10), CONVERT(date, dbo.f_SplitString(body,1,'|'), 105), 23)) + ' ' + substring(dbo.f_SplitString(body,2,'|'),2,5) + ':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 * from @QuickData
where TicketDate between @dateFrom and @dateTo
order by 1 desc;