SPLIT_STRING in several 'paragraphs'

0

I'm trying to pick up this type of table:

In which I have a daily import for a dbo, I have now had difficulty doing the split_string of the comments, doing the respective cross with the ID.

The idea is to have as many rows as (Additional Comments) per person.

Text in the example:

02-06-2017 15:38:48 - Tiago Caeiro (Comentários adicionais)  
Para resolução  

31-05-2017 19:37:58 - Tiago Caeiro (Comentários adicionais)  
Enviado mail para equipa para validar as dúvidas/questões colocadas.  

31-05-2017 19:28:42 - Pedro Aparício (Comentários adicionais)  
Tiago,  se quiser, pode-me contactar agora.
    
asked by anonymous 09.06.2017 / 00:17

1 answer

0

Bruno, I initially thought about using the comments tab (blank line, which means double CR + LF) as the comments tab. It would be simple to implement, but it would not be a good strategy. So I opted to use the comment's date / time as the identifier for a new comment.

  

For the tests the following table was created:

-- código #1
CREATE TABLE tbComentário (
     Id varchar(20), 
     DataAbertura datetime,
     Comentários varchar(2000)
);

set dateformat dmy;
INSERT into tbComentário values
  ('Ticket116685', '4/5/2017 11:55:02', 
   '02-06-2017 15:38:48 - Tiago Caeiro (Comentários adicionais)
Para resolução

31-05-2017 19:37:58 - Tiago Caeiro (Comentários adicionais)
Enviado mail para equipa para validar as dúvidas/questões colocadas.

31-05-2017 19:28:42 - Pedro Aparício (Comentários adicionais)
Tiago, se quiser, pode-me contactar agora.');
go
  

The function code looks like this:

-- código #2
CREATE FUNCTION separaElementos (@ID varchar(20), @pComentários varchar(8000))
   returns @Comentários table (ID varchar(20), Seq int, dataC datetime, autorC varchar(100), textoC varchar(2000))
begin

-- analisa parâmetro
IF len(ltrim(@pComentários)) = 0
   or @pComentários is NULL
  return;

--
declare @xComentários varchar(8000), @pos1 int, @pos2 int;
declare @dataC varchar(30), @autorC varchar(100), @textoC varchar(2000), @Seq int;
declare @CRLF char(2) = char(13)+char(10);

set @xComentários= ltrim(rtrim(@pComentários)) + char(26);
set @Seq= 0;

while left(@xComentários, 1) <> char(26)
   begin
   --- obtém a data do comentário adicional
   set @pos1= patindex('%[0-3][0-9]-[0-1][0-9]-[0-2][0-9][0-9][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9] %', @xComentários);
   IF @pos1 = 0 break;
   set @dataC= substring(@xComentários, @pos1, 19)

   -- pula separador 
   set @pos1= charindex(' - ', @xComentários, (@pos1 +19));
   IF @pos1 = 0 break;
   set @pos1+= 3;

   --- obtém o autor do comentário
   set @pos2= charindex(' (Comentários', @xComentários, @pos1);
   IF @pos2 = 0 break;
   set @autorC= substring(@xComentários, @pos1, (@pos2 - @pos1));

   -- pula trecho " (Comentários adicionais)"
   set @pos1= @pos2 + len(' (Comentários adicionais)');
   IF substring(@xComentários, @pos1, 2) = @CRLF
     set @pos1+= 2;

   -- retira trecho anterior do ponteiro
   set @xComentários= substring(@xComentários, @pos1, 8000);
   set @pos1= 1;

   --  obtém posição final do comentário
   set @pos2= patindex('%[0-3][0-9]-[0-1][0-9]-[0-2][0-9][0-9][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9] %', @xComentários);
   if @pos2 = 0
     -- procura caractere finalizador (^Z)
     set @pos2= charindex(char(26), @xComentários, @pos1);
   if @pos2 = 0 break;

   --- obtém o texto do comentário
   set @textoC= substring(@xComentários, @pos1, (@pos2 - @pos1));
   -- retira CRLF duplo ao final, se houver
   IF right(@textoC, 4) = replicate(@CRLF, 2)
     set @textoC= left(@textoC, (len(@textoC) -4));

   -- retira trecho anterior do ponteiro
   set @xComentários= substring(@xComentários, @pos2, 8000);
   set @pos1= 1; 

   -- acrescenta informações de comentário na tabela de retorno
   set @Seq+= 1;
   INSERT into @Comentários values
      (@ID, @Seq, convert(datetime, @dataC, 103), @autorC, @textoC)
   end;
return;   
end;
go
  

Finally, to trigger the function, using the test data:

-- código #3
select T1.ID, T1.DataAbertura, T2.Seq, T2.dataC, T2.autorC, T2.textoC
   from tbComentário as T1
        outer apply dbo.separaElementos (T1.ID, T1.Comentários) as T2
go 
  

Here's the result:

    
10.06.2017 / 22:54