2011-05-13 20 views
6

Tengo datos en una tabla. Necesito copiarlo en otra mesa. Una de las columnas es cadena delimitada por texto. Entonces, lo que estoy pensando para seleccionar todas las columnas es insertar el valor de indentity y con la subconsulta para dividir en función del delimitador e insertarlo en otra tabla.Necesito dividir una cadena en una instrucción de selección e insertarla en la tabla

Aquí está el ejemplo de datos

ID  Name  City  Items 
1  Michael Miami  item|item2|item3|item4|item5 
2  Jorge Hallandale item|item2|item3|item4|item5 

copia Nombre, Ciudad a una tabla conseguir la identidad y dividir y copiar Artículos a otra tabla con la columna de identidad Valor

Así salida debe ser

Tabla de usuarios

UserID Name  City 
1  Michael Miami 
2  Jorge Hallandale 

...

Items table 

ItemID UserID Name 
1  1  Item 
2  1  Item2 
3  1  Item3 
4  1  Item4 
5  2  Item 
6  2  Item2 
7  2  Item3 
8  2  Item4 

No es muy seguro cómo hacerlo con T-SQL. Se apreciarán las respuestas con ejemplos

Respuesta

6

Puede crear su función personalizada para dividir la cadena en T-Sql. Luego puede usar la función Dividir como parte de un JOIN con su tabla base para generar los resultados finales de su declaración INSERT. Eche un vistazo a este post. Espero que esto ayude.

+0

Solo para aclarar la respuesta de Abdul (ojalá pueda agregar esta aclaración) ... entonces usaría la función Dividir como parte de un JOIN con su tabla base para generar los resultados finales de su declaración INSERT. –

1

¿Se puede lograr esto con la recursión? Mi T-SQL es oxidado pero esto puede ayudarle a enviar en la dirección correcta:

WITH CteList AS (
    SELECT 0 AS ItemId 
     , 0 AS DelimPos 
     , 0 AS Item_Num 
     , CAST('' AS VARCHAR(100)) AS Item 
     , Items AS Remainder 
    FROM Table1 
    UNION ALL 
    SELECT Row_Number() OVER(ORDER BY UserID) AS ItemId 
     , UserID 
     , CASE WHEN CHARINDEX('|', Remainder) > 0 
       THEN CHARINDXEX('|', Remainder) 
       ELSE LEN(Remainder) 
      END AS dpos 
     , Item_num + 1 as Item_Num 
     , REPLACE(Remainder, '|', '') AS Element 
     , right(Remainder, dpos+1) AS Remainder 
    FROM CteList 
    WHERE dpos > 0 
     AND ItemNum < 20 /* Force a MAX depth for recursion */ 
) 
SELECT ItemId 
    , Item 
FROM CteList 
WHERE item_num > 0 
ORDER BY ItemID, Item_Num 
3

Usted puede hacer esto utilizando XML y la cruz se aplican.

ver lo siguiente:

DECLARE @t table (ID int, Name varchar(20), City varchar(20), Items varchar(max)); 
INSERT @t 
SELECT 1,'Michael','Miami'  ,'item|item2|item3|item4|item5' UNION 
SELECT 2,'Jorge' ,'Hallandale','item|item2|item3|item4|item5' 

DECLARE @u table (UserID int identity(1,1), Name varchar(20), City varchar(20)); 
INSERT @u (Name, City) 
SELECT DISTINCT Name, City FROM @t 

DECLARE @i table (ItemID int identity(1,1), UserID int, Name varchar(20)); 

WITH cte_Items (Name, Items) as (
    SELECT 
     Name 
     ,CAST(REPLACE('<r><i>' + Items + '</i></r>','|','</i><i>') as xml) as Items 
    FROM 
     @t 
    ) 

INSERT @i (UserID, Name) 
SELECT 
    u.UserID 
    ,s.Name as Name 
FROM 
    cte_Items t 
    CROSS APPLY (SELECT i.value('.','varchar(20)') as Name FROM t.Items.nodes('//r/i') as x(i)) s 
    INNER JOIN @u u ON t.Name = u.Name 


SELECT * FROM @i 

Ver más aquí: http://www.kodyaz.com/articles/t-sql-convert-split-delimeted-string-as-rows-using-xml.aspx

Cuestiones relacionadas