update en un campo con procedimiento almacenado

20/05/2004 - 11:26 por Jomaweb | Informe spam
Hola

Tengo una tabla con datos de clientes. Y estoy haciendo un procedimiento que
cuando alguien elimina un cliente en una provincia automáticamente se
renumeran unos números identificadores que yo les doy (no sus identity).

Por ejemplo, si tengo
1->juan;
2->pedro;
3->paco;
4->manuel
y en mi aplicacion alguien elimina a Pedro (numero 2) el SP automáticamente
hace un UPDATE y asigna el numero 2 a paco y el 3 a manuel.

Pero hasta ahora no he descubierto cómo coger un SELECT y realizar un
MOVENEXT para ir actualizando el campo. Esto es lo que tengo, pero no
funciona porque no tengo manera de pasar al siguiente registro. ¿dónde me he
perdido?

DECLARE @ITERADOR INTEGER
DECLARE @ID_CLIENTE INTEGER
SET @ITERADOR=0
SELECT * FROM clientes WHERE provincia=@PROV

IF (@@ROWCOUNT<>0)
BEGIN

WHILE (@ROW<=@ITERADOR)
BEGIN
SELECT @ID_CLIENTE=ID_CLIENTE FROM CLIENTES
UPDATE CLIENTES SET CODIGO=@ITERADOR WHERE ID_CLIENTE=@ID_CLIENTE
SET @ITERADOR=@ITERADOR + 1
continue
END
set @mensaje= 'SE RENUMERARON LOS CLIENTES'

select @mensaje as mensaje

Preguntas similare

Leer las respuestas

#11 Rubén Vigón
20/05/2004 - 16:01 | Informe spam
A mí me funciona correctamente... prueba éste script:

CREATE TABLE #Prueba
(
Numero tinyint NOT NULL PRIMARY KEY,
Nombre varchar(20) NOT NULL
)
GO
INSERT INTO #Prueba (Numero, Nombre) VALUES (1, 'Juan')
INSERT INTO #Prueba (Numero, Nombre) VALUES (2, 'Pedro')
INSERT INTO #Prueba (Numero, Nombre) VALUES (3, 'Paco')
INSERT INTO #Prueba (Numero, Nombre) VALUES (4, 'Manuel')
INSERT INTO #Prueba (Numero, Nombre) VALUES (5, 'Jorge')
GO
SELECT * FROM #Prueba
GO
DELETE FROM #Prueba WHERE Numero IN (2, 4)
GO
SELECT * FROM #Prueba
GO
UPDATE P SET P.Numero = (SELECT COUNT(*) FROM #Prueba WHERE Numero <= P.Numero) FROM #Prueba P
GO
SELECT * FROM #Prueba
GO

Un saludo!

Rubén Vigón
Microsoft MVP Visual Basic
http://www.mvp-access.com/rubenvigon
Respuesta Responder a este mensaje
#12 Rubén Vigón
20/05/2004 - 16:03 | Informe spam
DECLARE @orden smallint
SET @orden = 0
UPDATE T SET @orden= @orden + 1, orden=@orden FROM #test T



¡¡Que solución tan elegante!! Ésta me la apunto...

Gracias, Miguel y Liliana!

Un saludo,

Rubén Vigón
Microsoft MVP Visual Basic
http://www.mvp-access.com/rubenvigon
Respuesta Responder a este mensaje
#13 Liliana Sorrentino
20/05/2004 - 16:24 | Informe spam
Es cierto Ulises, gracias por corregir mi error.
Saludos... Liliana.

"ulises" escribió en el mensaje
news:fb6e01c43e71$655f56b0$
Hola Liliana,

El problema que le veo es que vuelve a renumerar todo, lo
cual puede ocasionar que le puede cambiar la secuencia a
los registros anteriores al registro eliminado, he
modificado la sentencia para incorporarla como un triger,
usando tu datos :

DROP TABLE tempo
go
CREATE TABLE tempo
(orden smallint,
nombre char(10))
go
INSERT tempo SELECT 1, 'Juan'
INSERT tempo SELECT 2, 'Pepe'
INSERT tempo SELECT 3, 'Luis'
INSERT tempo SELECT 4, 'José'
INSERT tempo SELECT 5, 'Marco'
INSERT tempo SELECT 6, 'Ulises'

CREATE TRIGGER eliminaregistro ON tempo FOR DELETE
AS
DECLARE @cantidad int
UPDATE tempo SET @cantidad = ( SELECT COUNT(*) FROM
deleted where orden < tempo.orden ),
orden = orden - @cantidad
go

si eliminamos registros :

select * from tempo
delete from tempo where orden in (2)
select * from tempo
delete from tempo where orden in (1,4)
select * from tempo

tenemos los siguientes resultados :

orden nombre
-
1 Juan
2 Pepe
3 Luis
4 José
5 Marco
6 Ulises

orden nombre
-
1 Juan
2 Luis
3 José
4 Marco
5 Ulises

orden nombre
-
1 Luis
2 José
3 Ulises

Saludos,
Ulises


Hola,
No sé si este ejemplo te sirva, renumera todo desde 1


(fue Miguel Egea quien
publicó algo parecido a esto hace un tiempo).
Saludos... Liliana.

DROP TABLE #test
go
CREATE TABLE #test
(orden smallint,
nombre char(10))

INSERT #test SELECT 1, 'Juan'
INSERT #test SELECT 2, 'Pepe'
INSERT #test SELECT 3, 'Luis'
INSERT #test SELECT 4, 'José'

DELETE FROM #test WHERE orden = 2

SELECT * FROM #test

DECLARE @orden smallint SET @orden = 0
UPDATE T
SET @orden= @orden + 1, orden=@orden
FROM #test T

SELECT * FROM #test
go

"Jomaweb" escribió en el


mensaje
news:eUxzo$
Repito, la propuesta de Rubén me pone EL MISMO NUMERO




EN TODOS LOS
REGISTROS.
Yo necesito que sean consecutivos.


"Carlos Sacristan" <csacristan ARROBA mvps.org>




escribió en el mensaje
news:%
>
> No, no. Tanto la propuesta de Rubén como la mía




eliminan ese bucle,
> olvídate de él.
>
> Por otro lado, el libro de Fernando es excelente.




Sin duda alguna te
lo
> recomiendo. Luego, cuando tengas un poco más de




experiencia, otro libro
> imprescindible es el de Kalen Delaney: "A fondo SQL




Server 2000"
>
>
> Un saludo
>
> -
> "Sólo sé que no sé nada. " (Sócrates)
>
> Por favor, responder únicamente al foro
> Se agradece la inclusión de sentencias DDL
>
>
> "Jomaweb" escribió en el




mensaje
> news:
> > Si, es una idea excelente, pero me pierdo a la hora




de hacer el
MOVENEXT
> en
> > el bucle WHILE.
> >
> > Hay algo que no pillo y no sé que és. De todos




modos, ¿me recomendáis
el
> > libro de F. Guerrero "SQL Server 2000 programacion




con ejemplos" para
> > ponerme un poco las pilas con esto?
> >
> >
> > "Carlos Sacristan" <csacristan ARROBA mvps.org>




escribió en el mensaje
> > news:
> > >
> > > Lo que haces no es muy eficiente. Si lo que




necesitas es numerar
> esos
> > > códigos para que sean consecutivos, en vez de




hacer eso yo los
numeraría
> > en
> > > la sentencia de recogida de datos. Hay varias




técnicas para numerar
los
> > > registros de forma consecutiva, pero la más usada




es crear una
variable
> > > tabla dentro del procedimiento de devolución de




datos con la
estructura
> > que
> > > necesites más un campo con la propiedad Identity




activada. Por
ejemplo:
> > >
> > > DECLARE @clientesTABLE (id integer identity




(1,1) PRIMARY KEY,
> > > nombre varchar(50))
> > >
> > > Y a continuación insertas los datos ordenados por




el identificador
que
> > > tenían antes:
> > >
> > > INSERT @clientes(nombre)
> > > SELECT nombre FROM clientes ORDER BY




id_cliente
> > >
> > > Por último devuelves los datos y ya tendrías la




estructura que
> necesitas:
> > >
> > > SELECT * FROM @clientes
> > >
> > > Un saludo
> > >
> > > -
> > > "Sólo sé que no sé nada. " (Sócrates)
> > >
> > > Por favor, responder únicamente al foro
> > > Se agradece la inclusión de sentencias DDL
> > >
> > >
> > > "Jomaweb" escribió




en el mensaje
> > > news:
> > > > Hola
> > > >
> > > > Tengo una tabla con datos de clientes. Y estoy




haciendo un
> procedimiento
> > > que
> > > > cuando alguien elimina un cliente en una




provincia automáticamente
se
> > > > renumeran unos números identificadores que yo




les doy (no sus
> > identity).
> > > >
> > > > Por ejemplo, si tengo
> > > > 1->juan;
> > > > 2->pedro;
> > > > 3->paco;
> > > > 4->manuel
> > > > y en mi aplicacion alguien elimina a Pedro




(numero 2) el SP
> > > automáticamente
> > > > hace un UPDATE y asigna el numero 2 a paco y el




3 a manuel.
> > > >
> > > > Pero hasta ahora no he descubierto cómo coger




un SELECT y realizar
un
> > > > MOVENEXT para ir actualizando el campo. Esto es




lo que tengo, pero
no
> > > > funciona porque no tengo manera de pasar al




siguiente registro.
¿dónde
> > me
> > > he
> > > > perdido?
> > > >
> > > > DECLARE @ITERADOR INTEGER
> > > > DECLARE @ID_CLIENTE INTEGER
> > > > SET @ITERADOR=0
> > > > SELECT * FROM clientes WHERE provincia=@PROV
> > > >
> > > > IF (@@ROWCOUNT<>0)
> > > > BEGIN
> > > >
> > > > WHILE (@ROW<=@ITERADOR)
> > > > BEGIN
> > > > SELECT @ID_CLIENTE=ID_CLIENTE FROM




CLIENTES
> > > > UPDATE CLIENTES SET CODIGO=@ITERADOR




WHERE
> > ID_CLIENTE=@ID_CLIENTE
> > > > SET @ITERADOR=@ITERADOR + 1
> > > > continue
> > > > END
> > > > set @mensaje= 'SE RENUMERARON LOS




CLIENTES'
> > > >
> > > > select @mensaje as mensaje
> > > >
> > > >
> > >
> > >
> >
> >
>
>






.

Respuesta Responder a este mensaje
#14 Javier Loria
20/05/2004 - 17:22 | Informe spam
Hola:
Una alternativa:
==DROP TABLE Clientes
CREATE TABLE Clientes(
Nombre VARCHAR(40)
NOT NULL PRIMARY KEY
, Orden INT NOT NULL
UNIQUE
)

INSERT Clientes(Nombre, Orden)
SELECT 'juan', 1 UNION ALL
SELECT 'pedro', 2 UNION ALL
SELECT 'paco', 3 UNION ALL
SELECT 'manuel', 4
GO

CREATE TRIGGER Clientes_Del ON Clientes
FOR DELETE
AS
SET NOCOUNT ON
UPDATE Clientes
SET Orden=Orden - (SELECT COUNT(*)
FROM Deleted
WHERE Clientes.Orden>Deleted.Orden)
WHERE Orden>(SELECT MIN(Orden) FROM Deleted)
GO
== La condicion del WHERE del UPDATE no es Totalmente necesaria pero ayuda
al desempeno.
El UPDATE resta la cantidad de filas eliminadas que eran previas al
numero actual. Por ejemplo si eliminamos las filas 2 y 4; cuando estemos en
la fila 1 el COUNT dara 0, cuando estemos en la fila 3 dara 1 y cuando
estemos en 5 o mas dara 2. Restando dicho numero a cada uno tenemo: 1-0=1,
3-1=2, 5-2=3, etc.
Varios comentarios adicionales:
a) Me preocupa particularmente cuando dices: <<se renumeran sus
identificadores>>. No me digas que esto significa que quieres cambiar los
valores de las llaves primarias?, porque esto seria desastroso para
cualquier sistema. Las llaves primarias son la identidad de la fila,
normalmente son inmutables y cuando cambian lo hacen esporadicamente.
b) Como viste de los aportes de Ruben, Carlos, Liliana y Ulises, en SQL
somos alergicos a los WHILE. Usarlos es mal sintoma, que estas pensando en
terminos procedimentales y no de conjuntos de datos.
c) En este codigo Orden puede ser calculado con los procedimientos que
postearon, lo cual hace que te cuestiones la existencia de la misma.
Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

Jomaweb escribio:
Hola

Tengo una tabla con datos de clientes. Y estoy haciendo un
procedimiento que cuando alguien elimina un cliente en una provincia
automáticamente se renumeran unos números identificadores que yo les
doy (no sus identity).

Por ejemplo, si tengo
1->juan;
2->pedro;
3->paco;
4->manuel
y en mi aplicacion alguien elimina a Pedro (numero 2) el SP
automáticamente hace un UPDATE y asigna el numero 2 a paco y el 3 a
manuel.

Pero hasta ahora no he descubierto cómo coger un SELECT y realizar un
MOVENEXT para ir actualizando el campo. Esto es lo que tengo, pero no
funciona porque no tengo manera de pasar al siguiente registro.
¿dónde me he perdido?

DECLARE @ITERADOR INTEGER
DECLARE @ID_CLIENTE INTEGER
SET @ITERADOR=0
SELECT * FROM clientes WHERE provincia=@PROV

IF (@@ROWCOUNT<>0)
BEGIN

WHILE (@ROW<=@ITERADOR)
BEGIN
SELECT @ID_CLIENTE=ID_CLIENTE FROM CLIENTES
UPDATE CLIENTES SET CODIGO=@ITERADOR WHERE
ID_CLIENTE=@ID_CLIENTE SET @ITERADOR=@ITERADOR + 1
continue
END
set @mensaje= 'SE RENUMERARON LOS CLIENTES'

select @mensaje as mensaje
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida