У нас есть старый пакет DTS, который наш сервер SQL 2000 использует для передачи записей о сотрудниках на машины в нашем производственном цеху.
Недавно мы обновили одну из машин, и теперь на ней работает SQL 2008 Express.
Мы перенастроили пакет DTS, чтобы отправить записи сотрудников на этот новый сервер, но теперь мы получаем это сообщение об ошибке:
FETCH_EMPLOYEES:
Заявление было прекращено. Не удается вставить повторяющуюся ключевую строку в объект «dbo.Users» с уникальным индексом «IX_tblUsers_OpID».

Если я удаленно подключаюсь к нашему серверу SQL 2000, я могу щелкнуть правой кнопкой мыши, чтобы последовательно выполнить каждый шаг пакета DTS без ошибок.

Итак, я вхожу в экземпляр SQL 2008 Express этой машины, чтобы посмотреть, смогу ли я что-нибудь выяснить.
Теперь я смотрю на хранимую процедуру FETCH_EMPLOYEES:
PROCEDURE [dbo].[FETCH_EMPLOYEES] AS
DECLARE @OpID varchar(255)
DECLARE @Password varchar(50)
DECLARE Employee_Cursor CURSOR FOR
SELECT OpID, Password
FROM dbo.vw_Employees
OPEN Employee_Cursor
FETCH NEXT FROM Employee_Cursor
INTO @OpID,@Password
WHILE @@FETCH_STATUS = 0
BEGIN
insert into dbo.Users (OpID,Password,GroupID)
VALUES (@OpID,@Password,'GROUP01')
FETCH NEXT FROM Employee_Cursor
INTO @OpID,@Password
END
CLOSE Employee_Cursor
DEALLOCATE Employee_Cursor
Я не особо разбираюсь в курсорах, но могу сказать, что данные извлекаются из представления vw_Employees и вставляются в таблицу dbo.Users.
Вид vw_Employees прост:
SELECT DISTINCT FirstName + ' ' + LastName AS OpID, Num AS Password
FROM dbo.EmployeeInfo
WHERE (Num IS NOT NULL) AND (FirstName IS NOT NULL)
AND (LastName IS NOT NULL) AND (Train IS NULL OR Train <> 'EX')
Итак, теперь кажется, что проблема должна быть в таблице dbo.Users.

Я не заметил, чтобы это привлекло какое-то особое внимание, поэтому я написал сценарий этой таблицы, используя CREATE TO Query Editor, и получил эту информацию, которую я действительно не понимаю:
CREATE TABLE [dbo].[Users](
[ID] [int] IDENTITY(1,1) NOT NULL,
[OpID] [nvarchar](255) NOT NULL,
[Password] [nvarchar](50) NOT NULL,
[GroupID] [nvarchar](10) NOT NULL,
[IsLocked] [bit] NOT NULL,
CONSTRAINT [PK_tblUsers] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Users] WITH CHECK ADD CONSTRAINT [FK_tblUsers_tblGroups] FOREIGN KEY([GroupID])
REFERENCES [dbo].[Groups] ([GroupID])
GO
ALTER TABLE [dbo].[Users] CHECK CONSTRAINT [FK_tblUsers_tblGroups]
GO
ALTER TABLE [dbo].[Users] ADD CONSTRAINT [DF_tblUsers_IsLocked] DEFAULT ((0)) FOR [IsLocked]
GO
Хорошо, я чувствую, что проблема где-то в этом определении таблицы, но я действительно не понимаю, что она делает (после создания базовой таблицы).
В нем есть раздел CONSTRAINT с множеством переменных, которые я не понимаю, затем он изменяет эти таблицы, добавляя FOREIGN KEY и CONSTRAINTS.
Мой вопрос: может ли кто-нибудь помочь мне понять, о чем мне говорит ошибка (кроме нарушения двойного ключа).
Какой столбец может вызывать дублирование ключа?
Включил ли я достаточно данных и скриншотов?
ОБНОВЛЕНИЕ:
Основываясь на комментариях, похоже, что этот скриншот необходим.
В таблице Пользователи есть список индексов, и один из них под названием IX_tblUsers_OpID говорит, что он уникальный и некластеризованный.
Я думаю, что мы устранили повторяющиеся значения Op_ID в нашей таблице исходных данных EmployeeInfo, найдя их все с помощью этого скрипта:
select num as 'Op_ID', count(num) as 'Occurrences'
from employeeInfo
group by num
having 1<count(num);
Это должно было избавиться от всех моих дубликатов. Правильно?
Мы покупаем производственные машины, которые поставляются с ПК для хранения локальных данных. Они предоставляют этот сценарий, который я разместил, поэтому я не могу комментировать, почему они выбрали именно то, что сделали. Мы просто запускаем задание, которое загружает данные на наш сервер.


IX_tblUsers_OPID. В приведенном выше сценарии я не вижу этого индекса. Есть ли шанс, что вы написали сценарий из неправильного места? - person billinkc   schedule 08.10.2013IX_tblUsers_OpID) он кажется в столбцеOpID(хотя мне это кажется неправильным). В любом случае, можете ли вы опубликовать это определение индекса? С другой стороны, ваш sp, похоже, не проверяет наличие строк в этой таблице, он просто вставляет их все (я также не вижу причин использовать там курсор) - person Lamak   schedule 08.10.2013Indexes, в том числе под названиемIX_btlUsers_OpID. Компания-производитель поставляет свои машины с уже установленными базами данных и скриптами. Мы просто пытаемся подключить наши старые пакеты DTS к этим новым машинам. - person jp2code   schedule 08.10.2013opIDпоступают из представления, и они состоят из этого:FirstName + ' ' + LastName, а не из этого столбцаnum- person Lamak   schedule 08.10.2013FirstName + ' ' + LastName? - person jp2code   schedule 08.10.2013INSERT(или вы всегда сначала удаляете эту таблицу?). Возможно, вы пытаетесь вставить уже существующую строку. - person Lamak   schedule 08.10.2013INSERT, но тогда я не разбираюсь в пакетах DTS. Я рассмотрю возможность разрешения повторяющихся записейFirstName + ' ' + LastNameиз нашей исходной базы данных. - person jp2code   schedule 08.10.2013