SQL Server: как заставить таблицу содержать одну строку? - PullRequest
70 голосов
/ 19 октября 2010

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

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

Ответы [ 10 ]

87 голосов
/ 19 октября 2010

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

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 из БД.

47 голосов
/ 19 октября 2010

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

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

Добавляя "DEFAULT 'X", вам никогда не придется иметь делоБлокируйте столбец, и вам не придется запоминать, какое значение было заблокировано при первой загрузке таблицы.

14 голосов
/ 19 октября 2010

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

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

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

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

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

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

5 голосов
/ 19 октября 2010

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

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

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

2 голосов
/ 11 марта 2015

Вот решение, которое я придумал для таблицы типа блокировки, которая может содержать только одну строку, содержащую 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';

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

2 голосов
/ 05 марта 2014

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

1 голос
/ 13 апреля 2015

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

CREATE TABLE [dbo].[Config](
[ID] [tinyint] IDENTITY(255,1) NOT NULL,
[Config1] [nvarchar](max) NOT NULL,
[Config2] [nvarchar](max) NOT NULL
1 голос
/ 19 октября 2010

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

0 голосов
/ 26 февраля 2013

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

0 голосов
/ 19 октября 2010
IF NOT EXISTS ( select * from table )
BEGIN
    ///Your insert statement
END
...