Подтвердить что ты не робот

SQL Server: как ограничить таблицу одной строкой?

Я хочу сохранить одну строку в таблице конфигурации для моего приложения. Я хотел бы подчеркнуть, что эта таблица может содержать только одну строку.

Каков самый простой способ принудительного ограничения одной строки?

4b9b3361

Ответ 1

Вы убедитесь, что один из столбцов может содержать только одно значение, а затем сделать это первичным ключом (или применить ограничение уникальности).

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

У меня есть несколько этих таблиц в различных базах данных, в основном для сохранения конфигурации. Это намного лучше, зная, что если элемент конфигурации должен быть int, вы только когда-нибудь прочитаете int из БД.

Ответ 2

Обычно я использую подход Дэмиена, который всегда отлично работал у меня, но я также добавляю одно:

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')
)

Добавив "ПО УМОЛЧАНИЮ" X, вам никогда не придется иметь дело со столбцом "Заблокировать", и не нужно будет помнить, какое значение блокировки было при загрузке таблицы в первый раз.

Ответ 3

Возможно, вы захотите переосмыслить эту стратегию. В подобных ситуациях я часто считаю неоценимым оставить старые строки конфигурации, лежащие вокруг исторической информации.

Для этого на самом деле у вас есть дополнительный столбец creation_date_time (дата/время вставки или обновления) и триггер вставки или вставки/обновления, который будет правильно заполнять текущую дату/время.

Затем, чтобы получить текущую конфигурацию, вы используете что-то вроде:

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

(в зависимости от вашего вкуса СУБД).

Таким образом, вы все равно можете сохранить историю для целей восстановления (вы можете внедрить процедуры очистки, если таблица становится слишком большой, но это маловероятно), и вы по-прежнему можете работать с последней конфигурацией.

Ответ 4

Вы можете внедрить INSTEAD OF Trigger, чтобы обеспечить применение этого типа бизнес-логики в базе данных.

Триггер может содержать логику, чтобы проверить, существует ли запись в таблице, и если да, ROLLBACK the Insert.

Теперь, сделав шаг назад, чтобы посмотреть на более крупную картинку, интересно, может быть, есть альтернативный и более подходящий способ хранения этой информации, возможно, в файле конфигурации или переменной среды, например?

Ответ 5

Я использую поле бит для первичного ключа с именем IsActive. Таким образом, может быть не более двух строк, а sql для получения допустимой строки: выберите * из настроек, где IsActive = 1 если таблица называется "Настройки".

Ответ 6

Вот решение, которое я придумал для таблицы блокировки, которая может содержать только одну строку, содержащую Y или N (например, состояние блокировки приложения).

Создайте таблицу с одним столбцом. Я поставил ограничение проверки на один столбец, чтобы в него можно было положить только Y или N. (Или 1 или 0 или что-то еще)

Вставьте одну строку в таблицу с "нормальным" состоянием (например, N означает не заблокировано)

Затем создайте триггер INSERT в таблице, который имеет только SIGNAL (DB2) или RAISERROR (SQL Server) или RAISE_APPLICATION_ERROR (Oracle). Это делает так, что код приложения может обновлять таблицу, но любой INSERT терпит неудачу.

Пример 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';

Работает для меня.

Ответ 7

Вы можете написать триггер действия вставки в таблице. Всякий раз, когда кто-то пытается вставить новую строку в таблицу, устраните логику удаления последней строки в триггерном коде вставки.

Ответ 8

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

Ответ 9

Здесь мы также можем сделать невидимое значение, которое будет таким же после первой записи в базе данных. Пример: Таблица студентов: Id: ИНТ Имя: char Здесь, в поле ввода, мы должны указать одно и то же значение для столбца id, которое будет ограничено после первой записи, кроме записи блокировки bla bla из-за ограничения первичного ключа, таким образом, имея только одну строку навсегда. Надеюсь, это поможет!

Ответ 10

Старый вопрос, но как насчет использования IDENTITY (MAX, 1) небольшого типа столбца?

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