SQL Server: cómo limitar una tabla que contiene una sola fila?

Quiero guardar una sola fila en una tabla de configuración para mi aplicación. Me gustaría aplicar esta tabla puede contener una única fila.

¿Cuál es la forma más sencilla de hacer cumplir la fila única restricción ?

  • ¿Por qué no usar una tabla con columnas (Name, Value) con una clave principal en el Nombre. A continuación, puede select Value from Table where Name = ? con la certeza de que no hay filas o una fila será devuelto.
  • No estoy seguro de sql es la mejor solución. Tal vez un simple archivo xml es el más adecuado para la configuración. Yo uso para pensar que la configuración != de datos y sql se hace para los datos.
  • He visto que salen mal cuando usted está esperando para leer, por ejemplo, un entero, y usted consigue un poco de mal formateados valor en la columna valor.
  • Por qué tendría que pasar? Porque especificó un inexistente valor para Name?
  • tenga en cuenta que mi comentario era una respuesta a ars comentario. La cuestión es, si vas a almacenar los pares nombre/valor, el valor bastante bien tiene que ser de la cadena, y no tienes medios de tutela de validación en la base de datos. Cuando se utiliza una sola fila de una tabla con columnas separadas para cada configuración (como el OP quería), entonces usted puede aplicar fácilmente de validación para cada parámetro de configuración a través de la verificación de las restricciones.
InformationsquelleAutor Martin | 2010-10-19

10 Kommentare

  1. 90

    Que asegúrese de que una de las columnas sólo puede contener un valor y, a continuación, hacer que la clave principal (o aplicar una restricción de unicidad).

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

    Tengo un número de estas tablas en diversas bases de datos, principalmente para el almacenamiento de configuración. Es mucho más agradable a sabiendas de que, si la configuración del elemento debe ser un int, que usted sólo leer un int de la DB.

    • +1. Este es el enfoque Celko utiliza para auxiliar las constantes de la tabla en «SQL para Lacasitos»
    • Esto es tan simple como se pone. Gracias.
    • +1: solución Interesante. Yo no había visto esto antes, así que gracias por compartir. Siempre de la forma, es fácil cuando se sabe cómo….
    • He aquí una pregunta de seguimiento a pensar más. ¿Cuál es la clave principal de esta tabla? 🙂
    • Creo que es natural que la clave sería {}, pero no estamos autorizados a implementar que en SQL.
    • Exactamente así! Por definición, la Cerradura puede ser clave, porque la clave debe ser irreductible. Pero SQL no tiene sintaxis que permite que el conjunto vacío es un elemento clave. Así que en este caso PRIMARY KEY != la clave principal.
    • Me gustaría ser un fraude si no he de admitir a la lectura.c.d.t y TTM, entre otras fuentes, de modo que su pregunta era un poco de un gimme.
    • Bueno, nosotros no conocía a este concepto, se estaba utilizando sin esta restricción para todos nuestros archivos de configuración. Gracias 🙂
    • ¿qué es c.d.t y TTM? Gracias por compartir tus recursos para que podamos aprender 🙂
    • c.d.t es la abreviatura de comp.databases.theory, un grupo de usenet (visible a través de grupos de Google) que admito que no he leído mucho de poco. Era más orientadas en torno a la teoría relacional de SQL – pero yo sabía que dportas/sqlvogel también frecuentaba el mismo grupo. TTM fue una referencia a la El Tercer Manifiesto, que es un buen libro hablando (de nuevo) sobre la teoría relacional en lugar de SQL.
    • genial, gracias por compartir!
    • Tiene el estándar SQL grupo considera que lo que es legal para alter table t add primary key ()?

  2. 48

    Yo normalmente uso Damien enfoque, que siempre ha trabajado muy bien para mí, pero también quiero añadir 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')
    )

    La adición de la «DEFAULT ‘X'», usted nunca tendrá que lidiar con el Bloqueo de la columna, y no tendrás que recordar que fue el valor de bloqueo cuando la carga de la tabla por primera vez.

    • La restricción predeterminada también debe ser nombrado o de lo contrario se obtendrá un autogenerado confuso nombre. Lock char(1) not null CONSTRAINT DF_T1_Lock DEFAULT 'X'
    • Además, usted debe tomar su valor predeterminado algo distinto de ‘X’. Hice el mío de una cadena más larga, y este es mi mensaje de error si intenta insertar una segunda fila: Violación de la restricción PRIMARY KEY ‘PK_RestrictToOneRow’. No se puede insertar clave duplicada en el objeto ‘dbo.1ROWTABLE’. El valor de clave duplicada es (Esta tabla está bloqueada en una fila).
  3. 14

    Usted puede desear reconsiderar esta estrategia. En situaciones similares, a menudo he encontrado que es invaluable para salir de la configuración antigua filas de la mentira en torno a la información histórica.

    De hacer eso, usted realmente tiene una columna adicional creation_date_time (fecha/hora de la inserción o actualización) y una inserción o insertar/actualizar gatillo que rellenar correctamente, con la fecha/hora actual.

    A continuación, con el fin de obtener su configuración actual, se usa algo como:

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

    (dependiendo del DBMS sabor).

    De esa manera, usted todavía consigue mantener la historia con fines de recuperación (usted puede iniciar los procedimientos de limpieza si la tabla se vuelve demasiado grande, pero esto es poco probable) y usted todavía consigue trabajar con la última configuración.

    • +1: oigo lo que usted está diciendo, pero yo prefiero al registro del historial de los cambios en la auditoría independiente de las tablas.
    • +1: Para compartir la interesante idea de la implementación de una pista de auditoría.
    • De niza. Sólo SELECT TOP 1 ... ORDER BY creation_date_time DESC
  4. 5

    Puede implementar un LUGAR DE Gatillo para hacer cumplir este tipo de lógica de negocio dentro de la base de datos.

    El gatillo puede contener la lógica para comprobar si ya existe un registro en la tabla y si es así, la REVERSIÓN de la Inserción.

    Ahora, dando un paso atrás para ver la imagen más grande, me pregunto si tal vez hay una alternativa y el modo más adecuado para almacenar esta información, tal vez en un archivo de configuración o la variable de entorno, por ejemplo?

    • +1 – puedo ver cómo el gatillo iba a trabajar, y tal vez voy a volver a caer en ese enfoque, pero me gusta Damien simple restricción. Hay una interesante discusión que se tenía en qué tipo de configuración de datos pertenece en el archivo de configuración y lo que pertenece en la DB. En este caso creo que el DB es el lugar correcto. No hay duda de que voy a vivir para lamentar esto… 🙂
  5. 2

    Yo uso un campo de bits de la clave primaria con el nombre de IsActive.
    Por lo tanto, pueden ser de 2 filas en la mayoría de las y y el sql para obtener la fila válida es:
    seleccione * de la Configuración de donde IsActive = 1
    si la tabla se llama Configuración.

  6. 2

    He aquí una solución que se me ocurrió para un bloqueo de tipo de tabla que puede contener sólo una fila, la celebración de una S o N (una aplicación de bloqueo de estado, por ejemplo).

    Crear la tabla con una columna. Puedo poner una restricción check en la columna, por lo que sólo una S o N se puede poner en él. (O 1 o 0, o lo que sea)

    Insertar una fila en la tabla, con el estado «normal» (por ejemplo, N significa que no bloqueado)

    A continuación, crear un desencadenador INSERT en la tabla que sólo tiene una SEÑAL (DB2) o RAISERROR (SQL Server) o RAISE_APPLICATION_ERROR (Oracle). Esto hace que sea tan código de la aplicación se puede actualizar la tabla, pero cualquier INSERTAR falla.

    DB2 ejemplo:

    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 mí.

  7. 1

    Puede escribir un disparo en la acción de inserción en la tabla. Cada vez que alguien intenta insertar una nueva fila en la tabla, lejos del fuego, de la lógica de la eliminación de la última fila en el desencadenador de inserción de código.

  8. 1

    Vieja pregunta pero, ¿cómo sobre el uso de la IDENTIDAD(MAX,1) de una pequeña columna tipo?

    CREATE TABLE [dbo].[Config](
    [ID] [tinyint] IDENTITY(255,1) NOT NULL,
    [Config1] [nvarchar](max) NOT NULL,
    [Config2] [nvarchar](max) NOT NULL
    • Se podría añadir otra fila con SET IDENTITY_INSERT.
  9. 0

    Aquí también podemos hacer invisible el valor que va a ser el mismo después de la primera entrada en la base de datos.Ejemplo:
    Estudiante De La Tabla:
    Id:int
    nombre:char
    Aquí en el cuadro de entrada,tenemos que especificar el mismo valor para la identificación de la columna que se va a restringir como después de la primera entrada distinta de bloqueo de escritura bla bla debido a la restricción de clave principal y por tanto sólo una fila para siempre.
    Espero que esto ayude!

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea