Как обновить 2 столбца в 2 таблицах с внешним ключом - PullRequest
5 голосов
/ 29 марта 2012

Я знаю, что вопрос о том, как обновить несколько таблиц в SQL, задавался ранее, и общий ответ, по-видимому, заключается в том, чтобы делать их отдельно в транзакции.

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

например.

Table1.a является внешним ключом для Table2.a

Одна из записей в таблицах неверна, например, оба столбца 'xxx' и должны быть 'yyy'

Как мне обновить Table1.a и Table2.a, чтобы они были 'yyy'?

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

Спасибо

Ответы [ 3 ]

10 голосов
/ 29 марта 2012

Вы не можете выполнить обновление одновременно, однако вы можете заставить SQL выполнить обновление. Вы должны убедиться, что ваши внешние ключи имеют инициируемое ссылочное действие ON UPDATE CASCADE

, например

ALTER TABLE YourTable
ADD CONSTRAINT FK_YourForeignKey
FOREIGN KEY (YourForeignKeyColumn) 
REFERENCES YourPrimaryTable (YourPrimaryKeyColumn) ON UPDATE CASCADE
2 голосов
/ 29 марта 2012

Не будучи фанатом каскада обновлений, я бы предложил другой маршрут.

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

2 голосов
/ 29 марта 2012

мой ответ основан на следующей ссылке: http://msdn.microsoft.com/en-us/library/ms174123%28v=SQL.90%29.aspx

Вам необходимо убедиться, что ваш table_constraint будет определен как ON UPDATE CASCADE

          CREATE TABLE works_on1
         (emp_no INTEGER NOT NULL,
          project_no CHAR(4) NOT NULL,
          job CHAR (15) NULL,
          enter_date DATETIME NULL,
          CONSTRAINT prim_works1 PRIMARY KEY(emp_no, project_no),
          CONSTRAINT foreign1_works1 FOREIGN KEY(emp_no) REFERENCES employee(emp_no) ON DELETE CASCADE,
          CONSTRAINT foreign2_works1 FOREIGN KEY(project_no) REFERENCES project(project_no) ON UPDATE CASCADE)

, а затем, когда вы будетеизмените значение вашего первичного ключа

, см. следующую цитату:

Для ON DELETE или ON UPDATE, если указана опция CASCADE, строка обновляется в ссылочной таблице, еслисоответствующая ссылочная строка обновляется в родительской таблице.Если НЕТ ДЕЙСТВИЯ указано, SQL Server Compact Edition возвращает ошибку, и действие обновления для указанной строки в родительской таблице откатывается.

Например, у вас может быть две таблицы, A и B, вбаза данных.Таблица A имеет ссылочную связь с таблицей B: внешний ключ A.ItemID ссылается на первичный ключ B.ItemID.

Если инструкция UPDATE выполняется для строки в таблице B и задано действие ON UPDATE CASCADEдля A.ItemID SQL Server Compact Edition проверяет наличие одной или нескольких зависимых строк в таблице A. Если такие существуют, обновляются зависимые строки в таблице A, как и строки, указанные в таблице B.

В качестве альтернативы,если не указано действие, SQL Server Compact Edition возвращает ошибку и откатывает действие обновления для указанной строки в таблице B, если в таблице A есть хотя бы одна строка, ссылающаяся на него.

...