SQL Server - Dividir Campos "$"

 
Vista:
sin imagen de perfil

Dividir Campos "$"

Publicado por Oscar Vangelis (6 intervenciones) el 12/09/2013 14:20:18
Que tal buenos días espero y puedan ayudarme quiero actualizar una tabla (MiTabla) ...en donde tengo una columna (nCompuesto) la tengo que dividir en 3 columnas separadas aPaterno, aMaterno y nombres quiero saber si alguien me puede ayudar con la consulta tipo o algo parecido

Update MiTabla Set aPaterno =
Update MiTabla Set aMaterno =
Update MiTabla Set nombres =

Mis Datos que tengo en nCompuesto son como estos:

"SILVA$LOPEZ$MIGUEL"
"HERNANDEZ$ANTONIO$FRANCISCO"
"LUGARDO$VICENTE$FLORIBERTO"
"LOPEZ$GUZMAN$HUGO LEONARDO"
"SALAS$PEREZ$ARACELI"
"VARELA$LEON$ALBERTO"
"VARELA$GARCIA$MATEO CELESTINO"
"SALINAS$HERNANDEZ$VERONICA"
"VARELA$LEON$IVAN"
"RAMIREZ$TINOCO$MA DE LA LUZ"
"UGALDE$FERRER$NANCY"
"RAMOS$MENCHACA$MARISELA"
"GONZALEZ$SIBAJA$ELOISA"
"IDA$NAKAMURA$REYNA VERONICA"
"AYALA$GONZALEZ$MARGARITA"
"GIL$GUZMAN$AUSTREBERTHA"
"CRUZ$GRANADA$GRACIELA"
"ESCUDERO$NOLASCO$MAURICIO"

Como pueden ver están separados por dolar ($) Intente ya con reverse charindex y substring y he obtenido resultados parciales me gustaría saber si ustedes saben como hacerlo exactamente

Muchas Gracias por su atención.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Isaias Islas Gonzalez
Val: 3.250
Oro
Ha mantenido su posición en SQL Server (en relación al último mes)
Gráfica de SQL Server

Dividir Campos "$"

Publicado por Isaias Islas Gonzalez (4558 intervenciones) el 12/09/2013 20:07:53
SQL Server no cuenta con una funcion que haga SPLIT, eso seria magnifico, pero puedes crear una funcion para resolver el problema:

FUNCION:


CREATE FUNCTION fnSplit
(
@Expression NVARCHAR(max)
, @Delimiter NVARCHAR(max)
, @INDEX INT
)
RETURNS NVARCHAR(max)
AS
BEGIN
DECLARE @RETURN NVARCHAR(max)
DECLARE @Pos INT
DECLARE @PrevPos INT
DECLARE @I INT
-- SELECT dbo.fnSplit('4.55.108.2','.', 2)
IF @Expression IS NULL OR @Delimiter IS NULL OR DATALENGTH(@Delimiter) = 0 OR @INDEX < 1
SET @RETURN = NULL
ELSE IF @INDEX = 1 BEGIN
SET @Pos = CHARINDEX(@Delimiter, @Expression, 1)
IF @Pos > 0 SET @RETURN = LEFT(@Expression, @Pos - 1)
END ELSE BEGIN
SET @Pos = 0
SET @I = 0
WHILE (@Pos > 0 AND @I < @INDEX) OR @I = 0 BEGIN
SET @PrevPos = @Pos
SET @Pos = CHARINDEX(@Delimiter, @Expression, @Pos + DATALENGTH(@Delimiter))

SET @I = @I + 1
END
IF @Pos = 0 AND @I = @INDEX
SET @RETURN = SUBSTRING(@Expression, @PrevPos + DATALENGTH(@Delimiter), DATALENGTH(@Expression))
ELSE IF @Pos = 0 AND @I <> @INDEX
SET @RETURN = NULL
ELSE
SET @RETURN = SUBSTRING(@Expression, @PrevPos + DATALENGTH(@Delimiter), @Pos - @PrevPos - DATALENGTH(@Delimiter))
END
RETURN @RETURN
END

Ejemplo del uso de la funcion:

Create table mytable (NombreCompuesto varchar(100), Nombre varchar(50), APaterno varchar(50), AMaterno varchar(50))
insert into mytable (NombreCompuesto) values('SILVA$LOPEZ$MIGUEL')
insert into mytable (NombreCompuesto) values('HERNANDEZ$ANTONIO$FRANCISCO')
insert into mytable (NombreCompuesto) values('LUGARDO$VICENTE$FLORIBERTO')
insert into mytable (NombreCompuesto) values('LOPEZ$GUZMAN$HUGO LEONARDO')
insert into mytable (NombreCompuesto) values('SALAS$PEREZ$ARACELI')
insert into mytable (NombreCompuesto) values('VARELA$LEON$ALBERTO')
insert into mytable (NombreCompuesto) values('VARELA$GARCIA$MATEO CELESTINO')
insert into mytable (NombreCompuesto) values('SALINAS$HERNANDEZ$VERONICA')
insert into mytable (NombreCompuesto) values('VARELA$LEON$IVAN')
insert into mytable (NombreCompuesto) values('RAMIREZ$TINOCO$MA DE LA LUZ')
insert into mytable (NombreCompuesto) values('UGALDE$FERRER$NANCY')
insert into mytable (NombreCompuesto) values('RAMOS$MENCHACA$MARISELA')
insert into mytable (NombreCompuesto) values('GONZALEZ$SIBAJA$ELOISA')
insert into mytable (NombreCompuesto) values('IDA$NAKAMURA$REYNA VERONICA')
insert into mytable (NombreCompuesto) values('AYALA$GONZALEZ$MARGARITA')
insert into mytable (NombreCompuesto) values('GIL$GUZMAN$AUSTREBERTHA')
insert into mytable (NombreCompuesto) values('CRUZ$GRANADA$GRACIELA')
insert into mytable (NombreCompuesto) values('ESCUDERO$NOLASCO$MAURICIO')

UPDATE mytable set Nombre = x.Nombre, APaterno = x.APaterno, AMaterno = x.AMaterno
FROM(
SELECT dbo.fnSplit(Nombrecompuesto, '$',1) as APaterno,
dbo.fnSplit(Nombrecompuesto, '$',2) as AMaterno,
dbo.fnSplit(Nombrecompuesto, '$',3) as Nombre,
NombreCompuesto
from mytable) AS X
JOIN mytable mt on mt.NombreCompuesto = x.NombreCompuesto
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil

Dividir Campos "$"

Publicado por Oscar Vangelis (6 intervenciones) el 13/09/2013 01:20:39
Voy a probarlo entre hoy y mañana y te digo como me fue Muchisismas Gacias!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Dividir Campos "$"

Publicado por Oscar Vangelis (6 intervenciones) el 13/09/2013 02:10:55
No funciono hermano se come una letra obtengo estos resultados mira

Nombre APaterno AMaterno
IGUEL SILVA OPEZ
RANCISCO HERNANDEZ NTONIO
LORIBERTO LUGARDO ICENTE
UGO LEONARDO LOPEZ UZMAN
RACELI SALAS EREZ
LBERTO VARELA EON
ATEO CELESTINO VARELA ARCIA

al parecer se come una o dos letras en el nombre y el apellido materno alguna idea? :D De todas formas muchas gracias por tomarte el tiempo para responderme
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Isaias Islas Gonzalez
Val: 3.250
Oro
Ha mantenido su posición en SQL Server (en relación al último mes)
Gráfica de SQL Server

Dividir Campos "$"

Publicado por Isaias Islas Gonzalez (4558 intervenciones) el 13/09/2013 19:37:18
Listo, funcion corregida

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
ALTER FUNCTION fnSplit
(
            @Expression NVARCHAR(max)
          , @Delimiter  NVARCHAR(max)
          , @INDEX      INT
      )
      RETURNS NVARCHAR(max)
      AS
      BEGIN
BEGIN
          DECLARE @RETURN  NVARCHAR(max)
          DECLARE @Pos     INT
          DECLARE @PrevPos INT
          DECLARE @I       INT
          -- SELECT dbo.fnSplit('4.55.108.2','.', 2)
          IF @Expression IS NULL OR @Delimiter IS NULL OR DATALENGTH(@Delimiter) = 0 OR @INDEX < 1
              SET @RETURN = NULL
          ELSE
              IF @INDEX = 1 BEGIN
                SET @Pos = CHARINDEX(@Delimiter, @Expression, 1)
              IF @Pos > 0
                SET @RETURN = LEFT(@Expression, @Pos - 1)
              END
          ELSE
              BEGIN
              SET @Pos = 0
              SET @I = 0
              WHILE (@Pos > 0 AND @I < @INDEX) OR @I = 0
                BEGIN
                  SET @PrevPos = @Pos
                  SET @Pos = CHARINDEX(@Delimiter, @Expression, @Pos + DATALENGTH(@Delimiter))
                  SET @I = @I + 1
                END
              IF @Pos = 0 AND @I = @INDEX
               BEGIN
                SET @RETURN = SUBSTRING(@Expression,  (@PrevPos + DATALENGTH(@Delimiter))-1, DATALENGTH(@Expression))
               END
              ELSE IF @Pos = 0 AND @I <> @INDEX
                  SET @RETURN = NULL
              ELSE
               BEGIN
                  SET @RETURN = SUBSTRING(@Expression, @PrevPos + (DATALENGTH(@Delimiter))-1, @PrevPos - DATALENGTH(@Delimiter)+1)
               END
          END
          RETURN @RETURN
      END
END
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Dividir Campos "$"

Publicado por Oscar Vangelis (6 intervenciones) el 13/09/2013 22:54:39
Muchas Gracias por tomarte la molestia de ayudarme en este tema de verdad, pero sigo teniendo problemas solamente con el campo del apellido materno algunos los hace bien y otros no mira te dejo un ejemplo con los resultados obtenidos por lo visto el apellido paterno y el nombre quedan excelente pero el apellido materno es el problema si pudieras ayudarme a resolverlo te estaria infinitamente agredecido sino tendre que exportar la base en pedazos para separar en excell y luego re importar no se me ocurre otra cosa mis conocimientos son limitados en este tema. Muchas Gracias Hermano!

JOAQUIN CHONG OCHOA
ARSENIO SANTIAGO LEON$ARS
MARCO ANTONIO GARCIA GARCIA
JORGE CHONG OCHOA
ORLANDO ULISES PEREDA OLMOS$
DANIEL RESENDIZ RODRIGUE
JENARO MERINO GARCIA
SILVIA EUGENIA BUJANOS WOLF$SI
AMADO GUZMAN PONCE$
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Isaias Islas Gonzalez
Val: 3.250
Oro
Ha mantenido su posición en SQL Server (en relación al último mes)
Gráfica de SQL Server

Dividir Campos "$"

Publicado por Isaias Islas Gonzalez (4558 intervenciones) el 14/09/2013 00:22:30
Bueno, tuve que recodificar la funcion, un poco de trabajo, pero creo que ya quedo, checala...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
ALTER FUNCTION [dbo].[fnSplit]
(
            @Expression NVARCHAR(max)
          , @Delimiter  NVARCHAR(max)
          , @INDEX      INT
      )
      RETURNS NVARCHAR(max)
      AS
      BEGIN
BEGIN
      DECLARE @RETURN  NVARCHAR(max)
      DECLARE @Pos     INT
      DECLARE @PrevPos INT
      DECLARE @I       INT
      -- Inicio de la logica
      IF @Expression IS NULL OR @Delimiter IS NULL OR DATALENGTH(@Delimiter) = 0 OR @INDEX < 1
          SET @RETURN = NULL
      ELSE
          IF @INDEX = 1
            BEGIN
             SET @Pos = CHARINDEX(@Delimiter, @Expression, 1)
             IF @Pos > 0
                SET @RETURN = LEFT(@Expression, @Pos - 1)
            END
      ELSE
          IF @INDEX = 2
            BEGIN
              SET @Expression = SUBSTRING(@Expression,CHARINDEX(@Delimiter,@Expression)+1,DATALENGTH(@Expression))
              SET @RETURN = SUBSTRING(@Expression, 1, CHARINDEX(@Delimiter,@Expression)-1)
            END
      ELSE
          IF @INDEX = 3
            BEGIN
              SET @Expression = SUBSTRING(@Expression,CHARINDEX(@Delimiter,@Expression)+1,DATALENGTH(@Expression))
              SET @Expression = SUBSTRING(@Expression,CHARINDEX(@Delimiter,@Expression)+1,DATALENGTH(@Expression))
              SET @RETURN = SUBSTRING(@Expression, 1, DATALENGTH(@Expression))
            END
          END
    RETURN @RETURN
 END
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Dividir Campos "$"

Publicado por Oscar Vangelis (6 intervenciones) el 14/09/2013 00:45:49
No queda hermano jaja yo creo que es imposible por que también estuve preguntando en otros foros con resultados parciales...

CREO LA FUNCION

CREATE FUNCTION fnSplit
(
@Expression NVARCHAR(max)
, @Delimiter NVARCHAR(max)
, @INDEX INT
)
RETURNS NVARCHAR(max)
AS
BEGIN
DECLARE @RETURN NVARCHAR(max)
DECLARE @Pos INT
DECLARE @PrevPos INT
DECLARE @I INT
-- SELECT dbo.fnSplit('4.55.108.2','.', 2)
IF @Expression IS NULL OR @Delimiter IS NULL OR DATALENGTH(@Delimiter) = 0 OR @INDEX < 1
SET @RETURN = NULL
ELSE IF @INDEX = 1 BEGIN
SET @Pos = CHARINDEX(@Delimiter, @Expression, 1)
IF @Pos > 0 SET @RETURN = LEFT(@Expression, @Pos - 1)
END ELSE BEGIN
SET @Pos = 0
SET @I = 0
WHILE (@Pos > 0 AND @I < @INDEX) OR @I = 0 BEGIN
SET @PrevPos = @Pos
SET @Pos = CHARINDEX(@Delimiter, @Expression, @Pos + DATALENGTH(@Delimiter))

SET @I = @I + 1
END
IF @Pos = 0 AND @I = @INDEX
SET @RETURN = SUBSTRING(@Expression, @PrevPos + DATALENGTH(@Delimiter), DATALENGTH(@Expression))
ELSE IF @Pos = 0 AND @I <> @INDEX
SET @RETURN = NULL
ELSE
SET @RETURN = SUBSTRING(@Expression, @PrevPos + DATALENGTH(@Delimiter), @Pos - @PrevPos - DATALENGTH(@Delimiter))
END
RETURN @RETURN
END

MODIFICO LA FUNCION

ALTER FUNCTION [dbo].[fnSplit]
(
@Expression NVARCHAR(max)
, @Delimiter NVARCHAR(max)
, @INDEX INT
)
RETURNS NVARCHAR(max)
AS
BEGIN
BEGIN
DECLARE @RETURN NVARCHAR(max)
DECLARE @Pos INT
DECLARE @PrevPos INT
DECLARE @I INT
-- Inicio de la logica
IF @Expression IS NULL OR @Delimiter IS NULL OR DATALENGTH(@Delimiter) = 0 OR @INDEX < 1
SET @RETURN = NULL
ELSE
IF @INDEX = 1
BEGIN
SET @Pos = CHARINDEX(@Delimiter, @Expression, 1)
IF @Pos > 0
SET @RETURN = LEFT(@Expression, @Pos - 1)
END
ELSE
IF @INDEX = 2
BEGIN
SET @Expression = SUBSTRING(@Expression,CHARINDEX(@Delimiter,@Expression)+1,DATALENGTH(@Expression))
SET @RETURN = SUBSTRING(@Expression, 1, CHARINDEX(@Delimiter,@Expression)-1)
END
ELSE
IF @INDEX = 3
BEGIN
SET @Expression = SUBSTRING(@Expression,CHARINDEX(@Delimiter,@Expression)+1,DATALENGTH(@Expression))
SET @Expression = SUBSTRING(@Expression,CHARINDEX(@Delimiter,@Expression)+1,DATALENGTH(@Expression))
SET @RETURN = SUBSTRING(@Expression, 1, DATALENGTH(@Expression))
END
END
RETURN @RETURN
END

EJECUTO

UPDATE vigentesdfnorte set Nombre = x.Nombre, APaterno = x.APaterno, AMaterno = x.AMaterno
FROM(
SELECT dbo.fnSplit(Nombrecompuesto, '$',1) as APaterno,
dbo.fnSplit(Nombrecompuesto, '$',2) as AMaterno,
dbo.fnSplit(Nombrecompuesto, '$',3) as Nombre,
NombreCompuesto
from vigentesdfnorte) AS X
JOIN vigentesdfnorte mt on mt.NombreCompuesto = x.NombreCompuesto

ME MANDA ESTE ERROR.

Mens. 537, Nivel 16, Estado 5, Línea 1
Se pasó un parámetro de longitud no válido a la función LEFT o SUBSTRING.
Se terminó la instrucción.

No quiero abusar de tu amabilidad si tienes oportunidad de ayudarme te lo agradecere muchisimo de antemano gracias por la retroalimentacion. Si se te complica es suficiente con lo que me haz ayudado Muchas Gracias!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Geri

Dividir Campos "$"

Publicado por Geri (17 intervenciones) el 14/09/2013 18:27:21
Supongo que estoes lo que buscas:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
If Object_ID('MiTabla','U') Is Not Null Drop Table MiTabla;
Create Table MiTabla(ID Int Identity Primary Key,
					nCompuesto Varchar(50));
Go
 
Insert Into MiTabla Select 'SILVA$LOPEZ$MIGUEL';
Insert Into MiTabla Select 'HERNANDEZ$ANTONIO$FRANCISCO';
Insert Into MiTabla Select 'LUGARDO$VICENTE$FLORIBERTO';
Insert Into MiTabla Select 'LOPEZ$GUZMAN$HUGO LEONARDO';
Insert Into MiTabla Select 'SALAS$PEREZ$ARACELI';
Insert Into MiTabla Select 'VARELA$LEON$ALBERTO';
Insert Into MiTabla Select 'VARELA$GARCIA$MATEO CELESTINO';
Insert Into MiTabla Select 'SALINAS$HERNANDEZ$VERONICA';
Insert Into MiTabla Select 'VARELA$LEON$IVAN';
Insert Into MiTabla Select 'RAMIREZ$TINOCO$MA DE LA LUZ';
Insert Into MiTabla Select 'UGALDE$FERRER$NANCY';
Insert Into MiTabla Select 'RAMOS$MENCHACA$MARISELA';
Insert Into MiTabla Select 'GONZALEZ$SIBAJA$ELOISA';
Insert Into MiTabla Select 'IDA$NAKAMURA$REYNA VERONICA';
Insert Into MiTabla Select 'AYALA$GONZALEZ$MARGARITA';
Insert Into MiTabla Select 'GIL$GUZMAN$AUSTREBERTHA';
Insert Into MiTabla Select 'CRUZ$GRANADA$GRACIELA';
Insert Into MiTabla Select 'ESCUDERO$NOLASCO$MAURICIO';
 
With T1 As
(Select	*,
		CharIndex('$',nCompuesto) Primer$,
		CharIndex('$',nCompuesto,CharIndex('$',nCompuesto)+1) Segundo$,
		Len(nCompuesto) Caracteres
From	MiTabla)
Select	*,
		Left(nCompuesto,Primer$-1) aPaterno,
		SubString(nCompuesto,Primer$+1,Segundo$-Primer$-1) aMaterno,
		SubString(nCompuesto,Segundo$+1,Caracteres-Segundo$)
From	T1;
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil

Dividir Campos "$"

Publicado por Oscar Vangelis (6 intervenciones) el 20/09/2013 03:01:24


Funciono!!!! Muchisimas Gracias !!! :D Excelente aporte Muchas gracias de verdad!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Dividir Campos "$"

Publicado por tabano (1 intervención) el 22/03/2016 15:32:47
Hola buenos dias, el ejemplo esta muy bueno. Me estoy volviendo loco tratando de separar en campos la informacion que esta en un solo campo deividido por el caracter que sea. Utilizando el ejemplo me funciona en el caso que sean siempre 3 datos que vienen en el campo. en mi caso no me funciona ya que no se de antemano cuantos datos voy a cortar. LEs paso un ejemplo.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
If Object_ID('MiTabla','U') Is Not Null Drop Table MiTabla;
Create Table MiTabla(ID Int Identity Primary Key,
					nCompuesto Varchar(250));
Go
 
Insert Into MiTabla Select 'PR-54-02320-483129,CO-54-02320-418138,CE-54-011-31302065';
Insert Into MiTabla Select 'CO-54-011-1555730886,PR-54-02202-430597,CE-54-011-55711586';
Insert Into MiTabla Select 'CO-54-011-49195926,PR-54-011-47579779,CE-54-011-69920562';
Insert Into MiTabla Select 'CO-54-011-49195926,PR-54-011-47579779';
Insert Into MiTabla Select 'CO-54-011-49195926,PR-54-011-47579779';
Insert Into MiTabla Select 'CO-54-011-49195926';
 
 
--
With T1 As
(
Select	*,
		CharIndex(',',nCompuesto) Primer$,
		CharIndex(',',nCompuesto,CharIndex(',',nCompuesto)+1) Segundo$,
		Len(nCompuesto) Caracteres
 
From	MiTabla
)
Select	*,
		Left(nCompuesto,Primer$-1) tel1,
		SubString(nCompuesto,Primer$+1,Segundo$-Primer$-1) tel2,
		SubString(nCompuesto,Segundo$+1,Caracteres-Segundo$)
From	T1;
;

Por favor alguien me podria dar una mano me estoy volviendo loco y necesito resolverlo.

Muchas gracias.

Saludos,
Gustavo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar