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;