Pregunta

Tengo dos tablas que ambos contienen 'tubería valores separó'

por ejemplo:

Tabla 1:

 DataField_A

 item 1|item 2|item 3|etc.....

Tabla 2:

 DataField_A

 item 7|item 5|item 3|etc.....

Necesito combinar la Tabla 2 en la tabla 1 de tal manera que la tabla 2 contiene todos los artículos a través de ambas tablas.

Hacer esto pro-gramaticalmente sería una simple cuestión de bucle a través de cada elemento en la tabla 2 y la adición a la tabla 1 si no existe en la tabla 1.

¿Cómo se puede hacer esto en SQL como un procedimiento almacenado?

¿Fue útil?

Solución

He utilizado una función de análisis (el ejemplo estoy usando viene de aquí ) para analizar la cadena en la Tabla 1. Luego utilizo esa función en un CTE para encontrar los elementos que faltan en la Tabla2 y combinar los datos.

/* Helper function to parse delimited string */
CREATE FUNCTION [dbo].[fnParseStringTSQL] (@string NVARCHAR(MAX),@separator NCHAR(1))
RETURNS @parsedString TABLE (string NVARCHAR(MAX))
AS 
BEGIN
   DECLARE @position int
   SET @position = 1
   SET @string = @string + @separator
   WHILE charindex(@separator,@string,@position) <> 0
      BEGIN
         INSERT into @parsedString
         SELECT substring(@string, @position, charindex(@separator,@string,@position) - @position)
         SET @position = charindex(@separator,@string,@position) + 1
      END
     RETURN
END
go

/* Set up some sample data */
declare @Table1 table (
    id int,
    DataField_1A varchar(500)
)

declare @Table2 table (
    id int,
    DataField_2A varchar(500)
)

insert into @Table1
    (id, DataField_1A)
    select 1, 'item 1|item 2|item 3'
    union
    select 2, 'item A|item B|item C|item D|item Z'

insert into @Table2
    (id, DataField_2A)
    select 1, 'item 7|item 5|item 3'
    union
    select 2, 'item A|item Y|item Z'

/* data before the update */
select * from @Table2

/* boolean to ensure loop executes at least once */
declare @FirstLoop bit
set @FirstLoop = 1

/* Do the updates */
while (@FirstLoop = 1 or @@ROWCOUNT <> 0) begin 
    set @FirstLoop = 0

    ;with cteMissingItems as (
    select t2.id, p.string
        from @Table2 t2
            inner join @Table1 t1
                on t2.id = t1.id
            cross apply dbo.fnParseStringTSQL(t1.DataField_1A,'|') p
        where charindex(p.string, t2.DataField_2A) = 0
    )
    update t2
        set t2.DataField_2A = t2.DataField_2A + '|' + mi.string
        from @Table2 t2
            inner join cteMissingItems mi
                on t2.id = mi.id
end /* while */

/* Prove the update worked */
select * from @Table2

/* Clean up */
drop function dbo.fnParseStringTSQL
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top