Ознаки
Якщо для отримання значень, вставлених у стовпець ідентичності, використовуються SCOPE_IDENTITY() або @@IDENTITY()), іноді вони повертають неправильні значення. Проблема виникає, лише коли запити використовують паралельні плани виконання. Докладні відомості про те, як визначити, чи використовуватимуться паралельні плани виконання запитів, див. в розділі Паралелізм інтрамережі в технічній статті завантаження Microsoft:
Причина
Корпорація Майкрософт підтверджує, що це проблема в продуктах Microsoft, які наведено на початку цієї статті.
Спосіб вирішення
Відомості про сукупне оновлення
SQL Server 2008 R2 з пакетом оновлень 1
Вирішення цієї проблеми вперше випущено в сукупному пакеті оновлень 5 для SQL Server 2008 R2 з пакетом оновлень 1. Щоб отримати докладні відомості про те, як отримати цей пакет сукупного оновлення, клацніть номер статті в базі знань Microsoft:
2659694Сукупний пакет оновлень 5 для SQL Server 2008 R2 з пакетом оновлень 1
Примітка.Оскільки збірки сукупні, кожен новий випуск виправлення містить усі виправлення та всі виправлення безпеки, які входять до складу попереднього випуску виправлення SQL Server 2008 R2. Радимо застосувати найновіший випуск виправлення, який містить це виправлення. Щоб отримати докладні відомості, клацніть номер цієї статті бази знань Microsoft:
2567616Збірки SQL Server 2008 R2, випущені після випуску SQL Server 2008 R2 з пакетом оновлень 1
Інші способи вирішення
Корпорація Майкрософт рекомендує не використовувати будь-яку з цих функцій у запитах, коли паралельні плани залучаються, оскільки вони не завжди надійні. Натомість скористайтеся реченням OUTPUT оператора INSERT, щоб отримати значення ідентичності, як показано в прикладі нижче.
Приклад використання речення OUTPUT:
DECLARE @MyNewIdentityValues(myidvalues int)
declare @A table (ID int primary key) Insert into @A values (1) declare @B (ID int primary key identity(1,1), B int not Null) Insert into @B values (1) виберіть [Кількість рядків] = @@RowCount, [@@IDENTITY] = @@IDENTITY, [SCOPE_IDENTITY] = SCOPE_IDENTITY() set statistics profile on Insert into _ddr_T вивід inserted.ID у @MyNewIdentityValues виберіть b.ID з @A а left join @B b on b.ID = 1 left join @B b2 on b2. B = -1 left join _ddr_T t on t.T = -1 де не існує (select * from _ddr_T t2, де t2.ID = -1) Set statistics profile off виберіть [Кількість рядків] = @@RowCount, [@@IDENTITY] = @@IDENTITY, [SCOPE_IDENTITY] = SCOPE_IDENTITY(), [IDENT_CURRENT] = IDENT_CURRENT('_ddr_T') виберіть * з @MyNewIdentityValues перейтиЯкщо вам потрібно використати будь-яку з цих функцій, скористайтеся одним із наведених нижче способів, щоб вирішити цю проблему.
Спосіб 1.
Включення до запиту наведеного нижче параметра
ВАРІАНТ (MAXDOP 1)
Примітка.Це може пошкодити продуктивність частини запиту SELECT.
Спосіб 2.
Прочитайте значення з частини SELECT у наборі змінних (або одну змінну таблиці), а потім вставте його в цільову таблицю за допомогою MAXDOP=1. Оскільки план INSERT не буде паралельним, ви отримаєте правильну семантичну схему, але ваш select буде паралельно для досягнення потрібної продуктивності.
Метод 3.
Запустіть наведену нижче інструкцію, щоб установити для параметра максимального ступеня паралелізму значення 1.
sp_configure 'максимальний ступінь паралелізму', 1
перейти
reconfigure with override
перейти
Примітка.Цей метод може призвести до погіршення продуктивності на сервері. Цей метод слід використовувати, тільки якщо ви не оцінили його під час тестування або складання середовища.
Додаткові відомості
Помилка Microsoft Connect у ційhttps://docs.microsoft.com/en-us/collaborate/connect-redirect