Principales respuestas
Eliminar un registro pero que no se elimine el código.

Pregunta
-
Un saludo a todos:
En una tabla tengo 3 columnas: "Código, área, descripción". El primary key lo tengo en el código, y necesito que sea un código consecutivo, entonces cuando ejecuto la instrucción de "eliminar" me elimina todo incluyendo el código y se pierde la codificación consecutiva, la pregunta es ¿Qué puedo hacer para que cuando ejecute la instrucción de "eliminar" no se pierda la consecutivo de las códigos?
Ejemplo:
Código área Descripción
TR-101-00 XXXX YYYYYYYYYY
TR-102-00 XXXX YYYYYYYYYY
TR-103-00 XXXX YYYYYYYYY
En el ejemplo anterior si elimino el TR-102-00, en la tabla vería los códigos TR-101-00 y TR-103-00, y lo que necesito es que cuando ejecute la instrucción "eliminar", y borro el TR-102-00, entonces en la tabla necesito ver TR-101-00 y TR-102-00.
Gracias de antemano.
Saludos
Respuestas
-
Que tal Alberto:
Gracias por tus comentarios, voy a trabajar en tus consejos y afortunadamente no voy a crear tablas muy grandes, de hecho van a ser muy pequeñas, entonces creo que el desempeño no se vería muy afectado, pero ya te platicaré cual fue el resultado.
Saludos!!
- Marcado como respuesta Pablo RubioModerator lunes, 3 de septiembre de 2018 18:45
-
De nada. Ademas que no te lo puse, dentro del procedure puedes utilizar un bloque try catch y si ocurre algo que no has controlado acometer en el mismo la excepcion bien sea lanzandola o realizando cualquier log...
Ya comentas como te fue.
Un saludo
- Marcado como respuesta Pablo RubioModerator lunes, 3 de septiembre de 2018 18:45
Todas las respuestas
-
Es decir, en resumidas cuentas quieres que cuando se elimina un registro entonces todos los registros cuyo código sea posterior al eliminado se actualicen para disminuir en una unidad su código. Esto va a ser costosísimo si la tabla es grande y eliminas uno de los códigos del principio.
Pero si a pesar de todo quieres hacerlo, se podría conseguir añadiendo un trigger sobre el DELETE y que dentro del trigger se haga algo parecido a esto: update laTabla set codigo = codigo-1 where codigo>codigoBorrado. Pero digo "parecido" porque en realidad tus códigos no son numéricos así que no basta con poner "codigo-1", tendrás que usar Substring, Left, Right y Len para trocear la parte numérica, decrementarla, y volver a combinar las partes. Y para hacer el trigger bien hecho tienes que prever el caso de que se borren varios registros de golpe, lo cual complica las cosas más.
Otra opción sería hacer lo mismo desde el código cliente, suponiendo que tengas un único programa cliente capaz de borrar esos registros. En ese caso, tienes la ventaja de que puedes forzar los borrados a que ocurran de uno en uno, con lo que se simplifica la condición del Update.
Pero si la tabla puede ser grande, y dado el coste de renumerar todos los registros cuando borras uno, se puede recurrir a otra opción, que es la de simplemente marcar el registro con algún código especial que signifique "borrado", y luego tener un proceso de renumeración que se ejecute cuando las reglase de negocio lo requieran y que recorra de una vez toda la tabla reajustando todos los códigos de una sola vez.
-
-
Hola Gabriel632:
Si bien los borrados son siempre conflictivos y más aun cuando hacen lo que tu pides, esta sería una posible solución, donde se intenta mantener lo que indicas, y además en un escenario de alta concurrencia.
Pero para poder aplicarla, te recomiendo que lo utilices dentro de un procedimiento almacenado, que no utilices nunca, directamente un borrado. Desde mi opinión cualquier otro escenario te sería imposible, de controlar, porque si ocurre un error de borrado. No tienes manera posible de controlarlo, y se produce un desbarajuste.....
CREATE TABLE codigos (Codigo VARCHAR(100) PRIMARY KEY, area VARCHAR(100), descripcion VARCHAR(100) ); GO INSERT INTO codigos (codigo, area, descripcion ) VALUES ('TR-101-00', 'XX', 'YY' ), ('TR-102-00', 'XX', 'YY' ), ('TR-103-00', 'XX', 'YY' ), ('TR-104-00', 'XX', 'YY' ), ('TR-105-00', 'XX', 'YY' ), ('TR-106-00', 'XX', 'YY' ); GO DELETE FROM CODIGOS WHERE CODIGO LIKE 'TR-103-00'; INSERT INTO codigos (codigo, area, descripcion ) VALUES ('TR-1010-00', 'XX', 'YY' ); GO CREATE PROCEDURE SP_BORRADOS(@CODIGO VARCHAR(100)) AS /*PUEDES CHEQUERAR SI EL CODIGO DE BORRADO NO ES EL ÚLTIMO */ BEGIN SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; declare @miCodigo int = (SELECT max(CAST(SUBSTRING(CODIGO, 4, CHARINDEX('-', CODIGO, 4)-4) AS INT) ) FROM codigos ) /* obtengo en maximo valor entero de la tabla */ declare @elEntrante int = (CAST(SUBSTRING(@codigo, 4, CHARINDEX('-', @codigo, 4)-4) AS INT)) IF (@miCodigo<>@elEntrante) BEGIN /*BLOQUEO DE TABLA PARA QUE NADIE INSERTE MIENTRAS TU BORRAS, AL FINALIZAR LA TRANSACCION SE DESBLOQUEA SOLA. */ ;WITH CTE AS ( SELECT ROW_NUMBER() OVER(ORDER BY CAST(SUBSTRING(CODIGO, 4, CHARINDEX('-', CODIGO, 4)-4) AS INT))+100 AS FILA, CAST(SUBSTRING(CODIGO, 4, CHARINDEX('-', CODIGO, 4)-4) AS INT) AS CADENA, CODIGO AS COD FROM CODIGOS) UPDATE A SET CODIGO = 'TR-'+CAST(C.FILA AS VARCHAR)+'-00' FROM CODIGOS A INNER JOIN CTE C ON C.COD = A.CODIGO WHERE FILA < CADENA; END ELSE DELETE FROM CODIGOS WHERE CODIGO =@CODIGO END; RETURN EXEC SP_BORRADOS 'TR-103-XX'; GO SELECT * FROM codigos
Espero te ayude.
Un saludo
-
Que tal Alberto:
Gracias por tus comentarios, voy a trabajar en tus consejos y afortunadamente no voy a crear tablas muy grandes, de hecho van a ser muy pequeñas, entonces creo que el desempeño no se vería muy afectado, pero ya te platicaré cual fue el resultado.
Saludos!!
- Marcado como respuesta Pablo RubioModerator lunes, 3 de septiembre de 2018 18:45
-
-
-
De nada. Ademas que no te lo puse, dentro del procedure puedes utilizar un bloque try catch y si ocurre algo que no has controlado acometer en el mismo la excepcion bien sea lanzandola o realizando cualquier log...
Ya comentas como te fue.
Un saludo
- Marcado como respuesta Pablo RubioModerator lunes, 3 de septiembre de 2018 18:45