Как я могу обработать нарушение первичного ключа в сценарии SQL без завершения сценария? - PullRequest
0 голосов
/ 14 марта 2012

Я очищаю огромную базу данных (SQL Server) и хочу знать, возможно ли удалить строку, если оператор обновления нарушает PK таблицы.

Я хочу что-то вроде этого:

UPDATE EMODCONCT SET CODPERLET = '2003' WHERE CODPERLET = '2003BI'
IF "UPDATE VIOLATES PK OF EMODCONCT" THEN
DELETE FROM EMODCONCT WHERE CODPERLET = '2003BI'
END
<DON'T SHOW ANY ERROR AND CONTINUE THE EXECUTION OF THE SCRIPT>

Существует ли какой-либо флаг для обнаружения ошибок такого типа и команда для продолжения выполнения без прерывания из-за ошибок?

Спасибо!

Ответы [ 3 ]

2 голосов
/ 02 июля 2012

Как насчет использования блока TRY CATCH.

BEGIN TRY
  UPDATE EMODCONCT SET CODPERLET = '2003' WHERE CODPERLET = '2003BI'
END TRY
BEGIN CATCH
  IF ERROR_NUMBER() = 2627  -- Violates Primary Key
    DELETE FROM EMODCONCT WHERE CODPERLET = '2003BI'
END CATCH
1 голос
/ 15 марта 2012

Ваши имена элементов данных и примеры данных мне не знакомы, поэтому я их поменяю:)

Допустим, первичный ключ для таблицы Orders является составной частью (product_name, customer_name). Есть строки для следующих предложений:

Colm orders freezer
Pete orders toaster
Ravi orders freezer
Ravi orders toaster

Требование: обновить, чтобы заменить все заказы на морозильники на заказы для тостеров, но если это вызывает нарушение PK, удалите нарушающие строки.

Colm orders freezer -> (row is altered to) Colm ordered toaster
Pete orders toaster -> (row is unaffected) Pete ordered toaster
Ravi orders freezer -> (row is deleted)
Ravi orders toaster -> (row is deleted)

Таким образом:

  1. Удалите строки, в которых у клиента есть заказы на и морозильник и тостер.
  2. Измените строки, в которых у клиента есть заказ на морозильник, чтобы он стал заказом на тостер.

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

1 голос
/ 14 марта 2012

Почему бы не проверить, содержит ли таблица значение первым, чтобы вы не получили ошибку?

IF EXISTS(SELECT NULL FROM EMODCONCT WHERE CODPERLET = @newId)
BEGIN
    DELETE FROM EMODCONCT WHERE CODPERLET = @oldId
END
ELSE
BEGIN
    UPDATE EMODCONCT 
        SET CODPERLET = @newId
    WHERE CODPERLET = @oldId
END
...