sql - registro - ¿Hay alguna forma de evitar la eliminación de filas en una tabla específica utilizando restricciones o desencadenadores?
restricciones en sql ejemplos (7)
¿Hay alguna manera de evitar la eliminación de filas en una tabla específica utilizando restricciones?
Me gustaría (por ejemplo) negar eliminación de fila si la identificación es 0,1 o 2
Esto es para evitar que los usuarios eliminen las cuentas maestras de una aplicación, y me gustaría evitarlo incluso si alguien lo intenta (por error) usando sql directamente.
¡Gracias!
EDITAR:
La idea de esta pregunta no es tocar la aplicación. No es una cuestión de seguridad, solo necesito saber si es posible hacer lo que solicité con restricciones o cualquier otra cosa que tenga SQL Server (no necesita ser una solución estándar de db).
EDICION 2:
Las muestras de código son muy, muy apreciadas: D
Estoy usando el siguiente disparador:
CREATE TRIGGER [dbo].[mytable_trd] ON [dbo].[mytable]
WITH EXECUTE AS CALLER
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON
DECLARE @tn varchar(255)
SELECT @tn = object_name(parent_obj)
FROM sysobjects
WHERE id = @@procid;
SET @tn = ''Deletes not allowed for this table: '' + @tn;
-- Add your code for checking the values from deleted
IF EXISTS(select * from deleted where mycolumn = 1)
RAISERROR (@tn, 16, 1)
END
GO
¿Estás seguro de que es cierto que nunca querrás que nadie elimine estas filas? ¿Incluso a ti mismo, o al dba? O trabajos de mantenimiento dbms?
Si solo se trata de algunos usuarios, necesitará algo así como una tabla de usuarios, con permisos, para poder consultarlo en el desencadenante y distinguir a los usuarios no autorizados de los usuarios autorizados.
En cuanto a imponer esto en una restricción , mi solución sería crear una tabla dependiente, por lo que las filas referenciadas no se pueden eliminar.
CREATE TABLE NoKillI (
id INT NOT NULL, FOREIGN KEY (id) REFERENCES Accounts(id) ON DELETE RESTRICT
);
INSERT INTO NoKillI (id) VALUES (0);
INSERT INTO NoKillI (id) VALUES (1);
INSERT INTO NoKillI (id) VALUES (2);
Ahora nadie puede eliminar filas en Accounts
con valores de id 0, 1 o 2, a menos que primero NoKillI
filas correspondientes en NoKillI
. Puede restringir las eliminaciones contra la tabla dependiente utilizando privilegios de SQL.
Para ello, escriba un activador de base de datos que active DELETE para la tabla en cuestión. Todo lo que necesita hacer es lanzar una excepción si el ID no es válido.
Podría intentar filtrar sus consultas mediante el uso de una función que compruebe para asegurarse de que el usuario no intente eliminar su cuenta maestra.
La solución que prefiero utiliza el modelo relacional y sus reglas de integridad.
Para cada registro en Tbl_Account
que no se puede eliminar, agregaría un registro en Tbl_AccountMaster
donde Tbl_Account.id_Account
es una clave externa. Tbl_AccountMaster
no está disponible para la actualización, excepto por el administrador de la base de datos. Nadie más puede eliminar los registros de Tbl_Account
que están vinculados a Tbl_AccountMaster
.
EDITAR: Acabo de notar que la misma idea se desarrolló aquí . ¡Gracias, Bill!
Si no confías en tus usuarios, agrega seguridad.
- Agregue un procedimiento almacenado que permita a los usuarios eliminar las filas que desean, pero no permita el que desee de acuerdo con sus propias reglas. Luego niegue el acceso de eliminación en la tabla, y permita ejecutar el acceso al sproc
- Agregue una tabla secundaria con referencias de clave externa, llame a la tabla Cuentas Maestras, o similar, niegue la actualización / elimine el acceso a esta tabla y añádale referencias a las cuentas en cuestión, esto evitará que alguien elimine una cuenta siempre que haya una referencia de esta tabla a ella
- Agregue un disparador, como sugiere OrbMan
- Agregue una vista donde puedan eliminar filas, haga que la vista omita todas las cuentas que no tienen permiso para eliminar, deniegue el acceso de eliminación a la tabla maestra y permita el acceso de eliminación para ver
Habiendo dicho eso, si tus usuarios tienen acceso suficiente para hablar con tu base de datos a través de SQL, entonces realmente solo estás pidiendo problemas. Debe reforzar la seguridad y solo permitir el acceso a la base de datos a través de su aplicación y protocolos establecidos. Entonces tienes muchas opciones para evitar problemas como este.