Как избежать двухэтапной вставки в SQL - PullRequest
2 голосов
/ 13 октября 2011

Допустим, у меня есть таблица, определенная следующим образом:

CREATE TABLE SomeTable
(
P_Id int PRIMARY KEY IDENTITY,
CompoundKey varchar(255) NOT NULL,
)

CompoundKey - это строка, в которой первичный ключ P_Id конкатенирован до конца, например, Foo00000001, который происходит из "Foo" + 00000001. В настоящий момент вставка записей в эту таблицу происходит в 2 этапа.

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

Я ищу способ полностью избежать 2-го обновления и сделать все это одним оператором вставки. Это возможно? Я использую MS SQL Server 2005.

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

Ответы [ 4 ]

5 голосов
/ 13 октября 2011

Вы можете использовать вычисляемый столбец;измените схему следующим образом:

CREATE TABLE SomeTable
(
P_Id int PRIMARY KEY IDENTITY,
CompoundKeyPrefix varchar(255) NOT NULL,
CompoundKey AS CompoundKeyPrefix + CAST(P_Id AS VARCHAR(10))
)

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

1 голос
/ 13 октября 2011

Две вещи:

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

2) Я бы воздержался от попыток вставить Id в конец CompoundKey в транзакции, триггере и т. Д. Это гораздо чище, если вам это нужно, например, на выходе. в запросах (select concat(CompoundKey, Id) as CompoundKeyId ...). Если вам нужен внешний ключ в других таблицах, просто используйте пару (CompoundKey, Id).

1 голос
/ 13 октября 2011

Это просто невозможно.
«Следующий идентификатор» не существует и, следовательно, не может быть прочитан для выполнения UPDATE до тех пор, пока строка не будет вставлена.

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

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

Я думаю, что ваша самая безопасная ставка - просто убедиться, что UPDATE находится в той же транзакции, что и INSERT, или использует триггер.Но, для академического аргумента этого, UPDATE все еще происходит.

1 голос
/ 13 октября 2011

A триггер легко выполнит это

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...