2015-02-18 3 views
-2

мне нужна помощь с моим кодом ... Мне нужно вставить в две таблицыВставка внешнего ключа

DECLARE @IDENTITY INT 

INSERT INTO BestallningMatratt (MatrattID, BestallningID, Antal) 
VALUES ('1', '2', '3') 

SELECT @IDENTITY = @@IDENTITY FROM BestallningMatratt 

INSERT INTO Bestallning (BestallningID, BestallningDatum, Totalbelopp, Levererad, KundID) 
VALUES (@IDENTITY, '28-02-2014', '250', '1', '1') 

Я получаю ошибку, когда я запускаю мой код

Msg 547, Level 16 , Состояние 0, Строка 2
Оператор INSERT противоречил ограничению FOREIGN KEY «FK_BestallningMatratt_Bestallning». Конфликт произошел в базе данных «Tomasos», таблице «dbo.Bestallning», в столбце «BestallningID».

Msg 544, Level 16, State 1, Line 4
Невозможно вставить явное значение для столбца идентификации в таблицу «Bestallning», если для параметра IDENTITY_INSERT установлено значение OFF.

+0

А с чем именно вам нужна помощь? –

+0

Не зная схему таблицы, это сложно сказать, но похоже, что вы пытаетесь вставить не в порядок. Сначала вам нужно добавить запись в «Bestallning», а затем вставить '@@ IDENTITY' в' BestallningMatratt.BestallningID'. –

+1

Я бы рекомендовал использовать ** 'SCOPE_IDENTITY()' ** вместо всего остального, чтобы захватить вновь вставленное значение идентификации. [См. Это сообщение в блоге для объяснения относительно WHY] (http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity -of-record /) –

ответ

0

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


Я бы настоятельно рекомендую вставить значение идентификатора, где вы можете избежать этого, плюс появляется, как если ваши операции по порядку. Похоже, BastallningMatratt - это дочерняя таблица, зависящая от FK от Bestallning. Предполагая, что в случае (и что вы еще нужно вставить ключ идентификации вручную в BestallningMatratt так, что ее ключ «1», попробуйте следующее:

SET IDENTITY_INSERT dbo.Tomasos ON; 
GO 

DECLARE @IDENTITY INT 

INSERT INTO Bestallning (BestallningDatum, Totalbelopp, Levererad, KundID) 
VALUES ('28-02-2014', '250', '1', '1') 

SELECT @IDENTITY = SCOPE_IDENTITY() 

INSERT INTO BestallningMatratt (MatrattID, BestallningID, Antal) 
VALUES ('1', @IDENTITY, '3') 

SET IDENTITY_INSERT dbo.Tomasos OFF; 
GO 
+1

Я проигнорировал это, потому что, хотя он может исправить сообщение об ошибке, вряд ли удастся исправить настоящую проблему. И если это не так, это приведет к значительно худшей проблеме с данными. Когда кто-то явно не понимает, что он делает, очень опасно предлагать практику, которую кто-то неопытный не должен использовать. – HLGEM

+0

Я не могу с этим спорить. :) –

2

FIrst, вы должны убедиться, что вы вставляют в таблицы в правильном порядке. Родительская таблица всегда первая, которую нужно вставить. Ваше сообщение об ошибке заставляет меня почувствовать, что это возможно здесь. Мне нужно было бы видеть, что фактические структуры таблиц являются постильными.

Далее в письменном коде вы должны знать структуру своих таблиц и знать, какие поля являются полями идентификаторов и НИКОГДА не пытаться вставлять их в те lds напрямую (если вы не дба, у которой много лет опыта). Особенно не из приложения или хранимой процедуры. Identity_insert - это особый случай передачи данных из одной системы в другую и НЕ должен использоваться ни для чего другого. Не следуйте указаниям для использования identity_insert на вашем текущем уровне знаний.

И, наконец, нет никаких обстоятельств, когда вы должны использовать идентификатор @@, чтобы получить значение идентификатора для вставки в другую таблицу. Вы можете получить неправильные результаты от этого, и это антиспам SQL для его использования. Если кто-то добавляет триггер в таблицу, которая вставляет в другую таблицу с идентификатором, это та, которая будет returend. SInce вы не можете предсказать, когда кто-то может это сделать, вероятно, вы обнаружите, что у вас есть проблема, когда целостность данных настолько перепутана, что почти невозможно исправить. Никогда не делайте ничего, что ставит под угрозу целостность данных. Лучший способ - использовать предложение OUTPUT, второй способ - использовать Scope_Identity(). @@ Идентичность очень рискованная, и если вы ее использовали в любом месте, ее следует немедленно заменить.