ОБНОВЛЕНИЕ: проблема не возникает при запуске с SQL Server 2008. Так что это странно (или неправильно) с SQL Server 2000.
Я пытаюсь сделать простую вставку в SQL Server 2000:
INSERT INTO UserAddresses (UserId, AddressId)
SELECT UserId, Id
FROM Addresses
и я получаю это:
Оператор INSERT конфликтует с
КОЛОНКА ИНОСТРАННЫЙ КЛЮЧ ограничение
'FK569ABB5045EE0940. Конфликт
произошло в базе данных «Заказы», таблица
«Адреса», столбец «Идентификатор».
Я хорошо знаю, что это значит, но не могу понять, почему происходит конфликт - обратите внимание, что я вставляю идентификаторы из таблицы адресов, чтобы они действительно существовали! Почему SQL Server не может найти их в конце внешнего ключа в таблице адресов? Должен ли я сделать глупо
SELECT * FROM Addresses
WHERE Id NOT IN (SELECT Id FROM Addresses)
или что?
Еще немного информации: идентификаторы - это GUID, данные поступают из устаревшей БД (импорт). Сначала я заполняю Адреса, затем пытаюсь вставить в UserAddresses. Если я выберу SELECT TOP 100 ... это работает ... так что это проблема с какой-то записью, но я не могу понять, почему это происходит.
CREATE TABLE [Addresses] (
[Id] [uniqueidentifier] NOT NULL ,
PRIMARY KEY CLUSTERED ([Id]) ON [PRIMARY] ,
) ON [PRIMARY]
CREATE TABLE [Users] (
[Id] [uniqueidentifier] NOT NULL ,
PRIMARY KEY CLUSTERED ([Id]) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [UserAddresses] (
[UserId] [uniqueidentifier] NOT NULL ,
[AddressId] [uniqueidentifier] NOT NULL ,
CONSTRAINT [FK569ABB5045EE0940] FOREIGN KEY
(
[AddressId]
) REFERENCES [Addresses] (
[Id]
),
CONSTRAINT [UserAddressesToAddressFK] FOREIGN KEY
(
[UserId]
) REFERENCES [Users] (
[Id]
)
) ON [PRIMARY]
ALTER TABLE Addresses ADD UserId UNIQUEIDENTIFIER
INSERT INTO Addresses (UserId, Id)
SELECT legacy_userid, legacy_single_useraddressid -- both are guids
FROM LegacyUsers INNER JOIN LegacyAddresses
ОБНОВЛЕНИЕ: Я только что сделал это без ошибок (пакет запросов завершен):
DECLARE c CURSOR FOR SELECT UserId, Id FROM Addresses
OPEN c
DECLARE @uid UNIQUEIDENTIFIER, @aid UNIQUEIDENTIFIER
FETCH NEXT FROM c INTO @uid, @aid
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @aid
INSERT INTO UserAddresses (UserId, AddressId)
VALUES (@uid, @aid)
FETCH NEXT FROM c INTO @uid, @aid
END
CLOSE c
DEALLOCATE c
Интересно, почему INSERT терпит неудачу, в то время как курсор foreach работает ...
ОБНОВЛЕНИЕ: упс, после завершения курсора, INSERT тоже работает. Но это никогда не работает автономно. Вот что я делаю:
- Запустите скрипт импорта, чтобы он заполнил таблицу адресов
- Вручную запустить INSERT - не получается
- Запустите CURSOR вручную - все работает
- DELETE FROM UserAddresses
- Вручную запустить INSERT - теперь работает
Это магия или я полный идиот, что-то упустил?
ОБНОВЛЕНИЕ: Если я делаю
ALTER TABLE UserAddresses DROP CONSTRAINT FK569ABB5045EE0940
INSERT INTO UserAddresses (UserId, AddressId)
SELECT UserId, Id
FROM Addresses
alter table UserAddresses
add constraint FK569ABB5045EE0940
foreign key (AddressId)
references Addresses
это тоже работает. Я думаю, что это ошибка в SQL Server 2000, несмотря на правило «никогда не вините компилятор».