Les données sources avec lesquelles je travaille, c'est tout dans une colonne appelée corps. Ces données ne peuvent malheureusement pas être modifiées. Les données arrivent via un email de l'extérieur de notre réseau, il entre alors dans Email2DB. E-mail2db est une application qui place les données de messagerie dans une table.
Ce n'est pas la manière dont les données sont généralement stockées dans nos tables, il s'agit d'une chose temporaire en place pour enregistrer des problèmes de PC de l'utilisateur, tout en éteignant le nombre de problèmes. peut être suivi. p>
corps p> à des fins de reporting, je divise les données dans des colonnes individuelles. P> J'ai besoin d'obtenir la date et l'heure distinctes pour être dans une colonne en tant que format DateTime.
Par exemple: J'essaie d'entrer les données dans la table TEMP suivante, mais pour la vie de moi, je ne peux pas obtenir la date et Il est temps de convertir en DateTime. p> si je modifie la table TICKEDATEDATEDATEDER pour être TICKEDATE VARCHAR (25) Les données vont bien. Cependant, l'objectif final est de pouvoir passer dans un @Datefrom et @Dateto et être capable de faire un service de billetterie entre @Datefrom et @dateto et je ne peux pas faire cela à moins que TICKEDATED est format DateTime. P> Qu'est-ce que je Je ne peux pas comprendre, c'est même si j'insère les données dans une table TEMP avec le ticket de Varchar, le résultat ressemble au dessous p> Résultat Si vous insérez TICKEDATED comme Varchar P> one Les données sont dans la table temporaire que j'ai essayée d'exécuter une instruction SELECT à l'aide de DateTime et de distribution En tant que DateTime2 et a également essayé de convertir en DateTime, mais rien ne fonctionne, je reçois toujours la même erreur p> La conversion a échoué lors de la conversion de la date et / ou du temps de la chaîne de caractères. P>
blockQuote> J'ajouterai l'une des tentatives que j'ai essayé ci-dessous si quelqu'un peut omettre, je serai si reconnaissant. P> S'il vous plaît savoir que j'ai des idées sans fin et essayé des multi-formats pour le Date heure. P> 2020-05-21 16:01 code> p>
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
4 Réponses :
Une option est d'analyser la chaîne via XML (JSON est une autre option si 2016)
Exemple fort> p> Declare @YourTable Table ([ID] varchar(50),[body] varchar(150)) Insert Into @YourTable Values
(1,'21/05/2020| 16:01| Pathe 2.0 Delay| Pathe| LRW10| terence')
Select A.ID
,DateCol = try_convert(datetime,Pos1+' '+Pos2,103)
,Issue = Pos3
,Category = Pos4
,PCName = Pos5
,[User] = Pos6
From @YourTable A
Cross Apply (
Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)')))
,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)')))
From ( values (cast('<x>' + replace((Select replace([body],'|','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml))) as A(xDim)
) B
Une autre approche consiste à créer une fonction valorisée de table comme celle-ci, qui renvoie une chaîne fractionnée dans l'ordre: alors vous pouvez pivoter cela pour extraire des éléments spécifiques: p> < Pré> xxx pré> p>
Meilleure datetime avec la cordon Concat
Vos chaînes de fonctions de fractionnement de la chaîne, vous perdez donc l'espace entre les composants de la date et de l'heure. P>
Changez votre code P>
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
Merci à tous pour vos suggestions. J'ai finalement compris le problème cependant. Lors de la conversion du temps, il y a un espace "non ordinaire", l'espace ne peut pas être retiré par la garniture et la solution utilisait donc la sous-chaîne et fonctionnait bien.
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;
Donc, ce
21/05/2020 | 16: 01 | PATHE 2.0 Délai | Pathe | LRW10 | Terence code> est une colonne i>? Je pense que vous devez repousser et obtenir des données dans votre base de données dans un format meilleur et plus normalisé. En ce moment, ce n'est pas une base de données, c'est un fichier texte.Avez-vous réellement essayé de construire votre requête dans des blocs individuels pour voir où il échoue? Dans mes tests simples (je n'ai pas votre implémentation de
f_splitstring code> fonction) ça fonctionne. Exécutez ceci:Sélectionnez Convert (date, dbo.f_splitstring (corps, 1, '|'), 105), converti (date, dbo.f_splitstring (corps, 1, '|'), 105), 23))) , Convertir (date, dbo.f_splitstring (corps, 1, '|'), 105), 23)) + dbo.f_splitstring (corps, 2, '|') code>. S'il échoue, continuez à supprimer des blocs de code de la fin jusqu'à ce que vous puissiez réellement le problème.@Aaronbertrand Les données entrent via un email d'une source externe non dans notre réseau, il passe ensuite par courrier électronique2DB. Cette application le met dans la table mais ne peut pas la séparer en différentes colonnes, pourquoi je suis bloqué avec de telles données difficiles à utiliser.
Cette chose de 20 ans ne peut rien faire sauf décharge ensemble complet de données dans une seule colonne? Peut-être qu'il est temps d'examiner différents logiciels.
Sur la base du fait que vous avez des espaces dans votre chaîne de texte, je soupçonne que votre fonction String Split se coupe et que vous perdez ainsi un espace entre les composants de la date et l'heure, je vous ai donc demandé de décoller votre requête pour trouver le problème. .