создание таблицы, если она не существует

Учитывая следующее:

if object_id('MyTable') is null create table MyTable( myColumn int )

Разве не возможно, чтобы два отдельных вызывающих объекта могли оценить object_id('MyTable') как null и, таким образом, оба попытались создать таблицу.

Очевидно, что один из двух вызывающих объектов в этом сценарии потерпит неудачу, но в идеале ни один вызывающий объект не должен сбой, скорее один должен заблокировать, а другой должен создать таблицу, тогда заблокированный вызывающий объект увидит object_id('MyTable') как ненулевой и продолжит работу.

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


person Ralph Shillington    schedule 05.10.2009    source источник


Ответы (4)


После первоначальной проверки используйте try catch при создании таблицы, и если ошибка заключается в том, что таблица уже существует, продолжайте, если нет, у вас более серьезная проблема.

person CaffGeek    schedule 05.10.2009

Обычно CREATE TABLE запускается из сценариев установки и установки, и неразумно ожидать, что сценарии установки разрешат параллельную установку из отдельных подключений.

Я рекомендую вам использовать блокировку приложения в рамках сеанса, полученную в начале процедуры установки/обновления, см. sp_getapplock.

person Remus Rusanu    schedule 05.10.2009

Я не думаю, что вам стоит беспокоиться об этом.

Операторы DDL не выполняются в рамках транзакции. Кроме того, 2-й вызывающий объект потерпит неудачу, если таблица уже была создана вызовом от 1-го вызывающего объекта.

person shahkalpeshp    schedule 05.10.2009
comment
как-то не волнуйтесь, будьте счастливы, что 2-й вызывающий абонент потерпит неудачу, это мало утешения. Я бы предпочел, чтобы второй вызывающий абонент продолжил работу без ошибок - person Ralph Shillington; 05.10.2009
comment
@Ralph: Имеет смысл. Как часто выполняется эта процедура? Почему вы хотите создать таблицу в процедуре? Это таблица, которую вы опустите в конце процедуры? Если нет, то почему бы не создать настоящую таблицу заранее? Пожалуйста, объясните свой сценарий, почему вы делаете такие вещи? - person shahkalpeshp; 05.10.2009

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

person HLGEM    schedule 05.10.2009
comment
-1 ответ соответствует достоинствам предполагаемого дизайна. Однако вопрос заключается в деталях реализации. - person Ralph Shillington; 05.10.2009
comment
Когда мы видим плохой дизайн, мы обязаны указать, что проблема может быть в дизайне, а не только в деталях реализации, о которых вы задаете вопрос. - person HLGEM; 05.10.2009
comment
@HLGEM В этом случае системное требование состоит в том, что многопоточная служба, использующая эту базу данных, может быть настроена или не настроена для записи информации об ошибках в таблицу аудита. Если настроена запись этой информации аудита, предполагается создать таблицу. Если таблица аудита ошибок не настроена, она не должна существовать, поскольку существующая, но пустая таблица аудита может указывать на то, что система работает нормально и ошибки не регистрируются. В двух словах это требование дизайна. - person Ralph Shillington; 05.10.2009