vistas vista usuarios usuario una tabla sobre privilegios permisos para otorgar datos dar crear asignar sql-server database-design singleton

sql-server - vista - permisos en sql server 2012



SQL Server: ¿cómo restringir una tabla para que contenga una sola fila? (10)

Quiero almacenar una sola fila en una tabla de configuración para mi aplicación. Me gustaría hacer cumplir que esta tabla puede contener solo una fila.

¿Cuál es la forma más simple de aplicar la restricción de fila única?


Aquí hay una solución que surgió para una tabla de tipo de bloqueo que puede contener solo una fila, manteniendo una Y o N (un estado de bloqueo de la aplicación, por ejemplo).

Crea la tabla con una columna. Puse una restricción de verificación en la columna para que solo se pueda poner una Y o N en ella. (O 1 o 0, o lo que sea)

Inserte una fila en la tabla, con el estado "normal" (por ejemplo, N significa que no está bloqueado)

A continuación, cree un desencadenador INSERTAR en la tabla que solo tenga SIGNAL (DB2) o RAISERROR (SQL Server) o RAISE_APPLICATION_ERROR (Oracle). Esto hace que el código de la aplicación pueda actualizar la tabla, pero cualquier INSERT falla.

Ejemplo de DB2:

create table PRICE_LIST_LOCK ( LOCKED_YN char(1) not null constraint PRICE_LIST_LOCK_YN_CK check (LOCKED_YN in (''Y'', ''N'') ) ); --- do this insert when creating the table insert into PRICE_LIST_LOCK values (''N''); --- once there is one row in the table, create this trigger CREATE TRIGGER ONLY_ONE_ROW_IN_PRICE_LIST_LOCK NO CASCADE BEFORE INSERT ON PRICE_LIST_LOCK FOR EACH ROW SIGNAL SQLSTATE ''81000'' -- arbitrary user-defined value SET MESSAGE_TEXT=''Only one row is allowed in this table'';

Funciona para mi.


Aquí también podemos hacer un valor invisible que será el mismo después de la primera entrada en la base de datos. Ejemplo: Student Table: Id: int firstname: char Aquí en el cuadro de entrada, tenemos que especificar el mismo valor para la columna id que restringirá como después de la primera entrada que no sea la de bloqueo bla bla debido a la restricción de clave primaria, teniendo así solo una fila para siempre. ¡Espero que esto ayude!


Asegúrese de que una de las columnas solo contenga un valor y luego conviértala en la clave principal (o aplique una restricción de exclusividad).

CREATE TABLE T1( Lock char(1) not null, /* Other columns */, constraint PK_T1 PRIMARY KEY (Lock), constraint CK_T1_Locked CHECK (Lock=''X'') )

Tengo varias de estas tablas en varias bases de datos, principalmente para almacenar config. Es mucho mejor saber que, si el elemento de configuración debe ser un int, solo leerá un int del DB.


Es posible que desee replantearse esta estrategia. En situaciones similares, a menudo me pareció invaluable dejar las viejas filas de configuración para información histórica.

Para hacerlo, en realidad tiene una columna adicional creation_date_time (fecha / hora de inserción o actualización) y un insert o insert / update trigger que lo completará correctamente con la fecha / hora actual.

Luego, para obtener su configuración actual, usa algo como:

select * from config_table order by creation_date_time desc fetch first row only

(dependiendo de tu sabor DBMS).

De esta forma, aún puede mantener el historial para fines de recuperación (puede establecer procedimientos de limpieza si la tabla es demasiado grande pero esto es poco probable) y aún puede trabajar con la última configuración.


Pregunta anterior, pero ¿qué hay de usar IDENTIDAD (MAX, 1) de un tipo de columna pequeña?

CREATE TABLE [dbo].[Config]( [ID] [tinyint] IDENTITY(255,1) NOT NULL, [Config1] [nvarchar](max) NOT NULL, [Config2] [nvarchar](max) NOT NULL


Puede escribir un desencadenador en la acción de inserción en la tabla. Cada vez que alguien intente insertar una nueva fila en la tabla, elimine la lógica de eliminar la última fila en el código de activación de inserción.


Puede implementar un desencadenador INSTEAD OF para aplicar este tipo de lógica empresarial dentro de la base de datos.

El disparador puede contener lógica para verificar si ya existe un registro en la tabla y, de ser así, ROLLBACK el Insertar.

Ahora, dando un paso atrás para ver la imagen más grande, me pregunto si tal vez hay una manera alternativa y más adecuada para que usted almacene esta información, tal vez en un archivo de configuración o variable de entorno, por ejemplo.


Usualmente uso el enfoque de Damien, que siempre me ha funcionado muy bien, pero también agrego una cosa:

CREATE TABLE T1( Lock char(1) not null DEFAULT ''X'', /* Other columns */, constraint PK_T1 PRIMARY KEY (Lock), constraint CK_T1_Locked CHECK (Lock=''X'') )

Agregando el "DEFAULT ''X''", nunca tendrá que lidiar con la columna de Bloqueo, y no tendrá que recordar cuál era el valor de bloqueo al cargar la tabla por primera vez.


Yo uso un campo de bit para la clave principal con el nombre IsActive. Entonces puede haber 2 filas como máximo y el sql para obtener la fila válida es: select * from Settings donde IsActive = 1 si la tabla se llama Settings.


IF NOT EXISTS ( select * from table ) BEGIN ///Your insert statement END