Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Тэй Member Откуда: Сообщений: 79 |
из файла в таблицу RemainsUploadRMS загружаются данные о поставщиках, имеющихся у них номенклатурах и т.д. После нам нужно обновить таблицу номенклатур. На ней стоит ограничение уникальности на сочетании столбцов ProducerId и Code При попытке вставки у меня выскакивает сообщение об ошибке Сообщение 2627, уровень 14, состояние 1, строка 28 Нарушение "UK_Nomen_CodeProducer" ограничения UNIQUE KEY. Невозможно вставить повторяющийся ключ в объект "dbo.Nomen". Хотя по моей логике я дублей не вставляю. CREATE TABLE tempNomen ( NomenCode varchar(50), NomenName varchar(256), ParentId bigint ) Insert into tempNomen SELECT DISTINCT NomenCode, NomenName, Producer.ParentId FROM RemainsUploadRMS INNER JOIN Producer ON Producer.Name LIKE RemainsUploadRMS.ProducerName Insert into Nomen (Code, Name, ProducerId) select f.NomenCode, tempNomen.NomenName, f.ParentId from ( SELECT NomenCode, ParentId FROM tempNomen EXCEPT SELECT Code, ProducerId FROM Nomen ) as f inner join tempNomen on ((tempNomen.NomenCode LIKE f.NomenCode) AND (tempNomen.ParentId = f.ParentId)) Помогите, пожалуйста, объясните, что я делаю не так. |
13 ноя 12, 09:16 [13462679] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47050 |
Тэй,inner join tempNomen on ...не обеспечивает отношение 1:1 А вообще, зачем лишняя таблица? Почему уникальна комбинация двух полей, а DISTINCT применяется к трём? Версия сервера какая? |
13 ноя 12, 09:30 [13462734] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
iap, версия сервера - 2008 у Nomen 4 поля - ID(ключ, автоинкремент) Code - код наименования , Name -имяТовара , ProducerId - производитель. RemainsUploadRMS содержит имя произв-ля, а нам нужен код. получаем его с помощью Join из Producer если такого в таблице нет, пропустить строку. А дистинкт можно к двум полям применить, а третье так оставить? я думала, он убирает повтор записи в целом. |
13 ноя 12, 09:36 [13462756] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47050 |
А для этих двух полей в другой таблице создан уникальный индекс! Producer.Name LIKE RemainsUploadRMS.ProducerName - эти поля VARCHAR(MAX) что ли? Иначе почему LIKE, а не =? Или ProducerName содержит шаблон для LIKE? INSERT Nomen(Code, Name, ProducerId) SELECT TOP(1) WITH TIES NomenCode, NomenName, Producer.ParentId FROM RemainsUploadRMS JOIN Producer ON Producer.Name LIKE RemainsUploadRMS.ProducerName WHERE NOT EXISTS(SELECT * FROM Nomen N WHERE N.Code=Nomen.Code AND N.ProducerId=Nomen.ProducerId) ORDER BY ROW_NUMBER()OVER(PARTITION BY NomenCode, Producer.ParentId ORDER BY NomenName);Может, так? Но непонятно, какое NomenName оставлять, если для одной и той же пары NomenCode, ParentId их несколько. Непонятно, почему Вы не используете алиасы и не снабжаете ими поля запроса, чтобы знать, откуда что берётся. |
||
13 ноя 12, 09:57 [13462846] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
iap, потому что я полный нуб, поэтому и не использую. И запросов не писала больше 2х лет( Producer.Name тип varchar(50). a like для строк использовала, тк думала, что просто = на строках не работает.
я предположила, что название NomenName может быть введено не совсем корректно, допустим, в другом регистре, с подчеркиванием вместо пробела. но если при этом номенкод и ProducerId такие уже есть, то не вставляем эту строку. п.с. оконные функции знаю, но что такое WITH TIES? п.с.2 спасибо за ответы, думала, все так легко сделаю и застопорилась...... |
||
13 ноя 12, 10:07 [13462882] Ответить | Цитировать Сообщить модератору |
PaulYoung Member Откуда: Москва Сообщений: 2565 |
|
||
13 ноя 12, 10:09 [13462892] Ответить | Цитировать Сообщить модератору |
PaulYoung Member Откуда: Москва Сообщений: 2565 |
|
||
13 ноя 12, 10:12 [13462905] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
iap, ваш запрос выдал Сообщение 4104, уровень 16, состояние 1, строка 7 Не удалось привязать составной идентификатор "Nomen.Code". Сообщение 4104, уровень 16, состояние 1, строка 7 Не удалось привязать составной идентификатор "Nomen.ProducerId". |
13 ноя 12, 10:17 [13462931] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
PaulYoung, я увидела базу в первый раз.... задание получила на пальцах... Так что да, то, что запомнила + то, что додумала... |
13 ноя 12, 10:21 [13462945] Ответить | Цитировать Сообщить модератору |
PaulYoung Member Откуда: Москва Сообщений: 2565 |
|
||
13 ноя 12, 10:24 [13462966] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47050 |
INSERT Nomen(Code, Name, ProducerId) SELECT TOP(1) WITH TIES RU.NomenCode, RU.NomenName, P.ParentId FROM RemainsUploadRMS RU JOIN Producer P ON RU.ProducerName=P.Name WHERE NOT EXISTS(SELECT * FROM Nomen N WHERE N.Code=RU.NomenCode AND N.ProducerId=P.ParentId) ORDER BY ROW_NUMBER()OVER(PARTITION BY RU.NomenCode, P.ParentId ORDER BY RU.NomenName); |
||
13 ноя 12, 10:29 [13462991] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
PaulYoung, ну если не правильного, то хоть работающего.... Блин, вы даже не представляете, как мне стыдно(((( Хочется закрыться дома на месяц с учебником по базам и зубрить-зубрить... |
13 ноя 12, 10:29 [13462992] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47050 |
Можно, кстати, и поиском по этому форуму воспользоваться. Сотни тем было, можете поверить |
||
13 ноя 12, 10:32 [13463008] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
iap, уже слазила и прочла давно, пока вы писали сообщение... это нервное просто, думала, мне быстро ткнут на мою ошибку. я ее исправлю и все, сдам задание. И все равно ваш запрос от этого не заработал. как и мой. |
13 ноя 12, 10:36 [13463042] Ответить | Цитировать Сообщить модератору |
PaulYoung Member Откуда: Москва Сообщений: 2565 |
|
||
13 ноя 12, 10:38 [13463060] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Ошибка Нарушение "UK_Nomen_CodeProducer" ограничения UNIQUE KEY. Невозможно вставить повторяющийся ключ в объект "dbo.Nomen". есть логическая ошибка Т.е. ваш запрос выбирает неверные данные |
||
13 ноя 12, 10:39 [13463068] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
Glory, о, а вот и кеп) |
13 ноя 12, 10:45 [13463122] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Даже кэп не может видеть, какие данные выбирает ваш запрос А у вас наверное смелости не хватает самой на них посмотреть |
||
13 ноя 12, 10:48 [13463142] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
PaulYoung, окей, вот задача из файла в таблицу RemainsUploadRMS загружаются данные о поставщиках, имеющихся у них номенклатурах и т.д. После нам нужно обновить таблицу номенклатур. На ней стоит ограничение уникальности на сочетании столбцов ProducerId и Code у Nomen 4 поля - ID(ключ, автоинкремент), Code - код наименования , Name - имяТовара , ProducerId - производитель. RemainsUploadRMS содержит имя произв-ля ProducerName, а нам нужен код. получаем его с помощью Join из Producer если такого в таблице Producer нет, пропустить строку. Если в таблице NOmen уже есть такое же сочетание полей ProducerId и Code, как в RemainsUploadRMS, то не вставляем строку. Что еще вам уточнить? |
13 ноя 12, 10:55 [13463180] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
Glory, тк запрос на вставку, то никакие. К сообщению приложен файл. Размер - 138Kb |
13 ноя 12, 11:05 [13463231] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Что никакие ? Какие записи нарушают UK_Nomen_CodeProducer ? Почему они попали в ваши запрос ? |
||
13 ноя 12, 11:07 [13463253] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
Glory, буду благодарна, если объясните, как это увидеть, какие именно записи вызывают ошибку. И если б я знала, почему они попали в запрос, то тему было бы создавать бессмысленно. среда пишет: (строк обработано: 979939) Сообщение 2627, уровень 14, состояние 1, строка 28 Нарушение "UK_Nomen_CodeProducer" ограничения UNIQUE KEY. Невозможно вставить повторяющийся ключ в объект "dbo.Nomen". Выполнение данной инструкции было прервано. надо смотреть строку 979939 запроса select f.NomenCode, tempNomen.NomenName, f.ParentId from ( SELECT NomenCode, ParentId FROM tempNomen EXCEPT SELECT Code, ProducerId FROM Nomen ) as f inner join tempNomen on ((tempNomen.NomenCode LIKE f.NomenCode) AND (tempNomen.ParentId = f.ParentId)) ?? Но насколько я знаю, он может каждый раз по-разному выполняться. или я не права? |
13 ноя 12, 11:15 [13463314] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Вы хоть выяснили, какой из ваших 2х запросов падает ? А к какому относится "строк обработано" ?А к какому "Выполнение данной инструкции было прервано." ?
Написать запрос на пересечние двух множеств ? Одно из которых таблица, куда идет добавление, а второе - ваш запрос, который будет добавлять данные ? Неужели кэпу нужно озвучивать такие аксиомы ? |
||||
13 ноя 12, 11:19 [13463349] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9636 |
Тэй, У вас либо в tempNomen есть записи с одинаковыми NomenCode и ParentId для разных NomenName, либо в Nomen уже есть записи, аналогичные добавляемым. Проверяется легко: CREATE TABLE tempNomen ( NomenCode varchar(50), NomenName varchar(256), ParentId bigint ) Insert into tempNomen SELECT DISTINCT NomenCode, NomenName, Producer.ParentId FROM RemainsUploadRMS INNER JOIN Producer ON Producer.Name LIKE RemainsUploadRMS.ProducerName Insert into Nomen (Code, Name, ProducerId) select f.NomenCode, tempNomen.NomenName, f.ParentId from ( SELECT NomenCode, ParentId FROM tempNomen EXCEPT SELECT Code, ProducerId FROM Nomen ) as f inner join tempNomen on ((tempNomen.NomenCode LIKE f.NomenCode) AND (tempNomen.ParentId = f.ParentId)) where not exists(select * from Nomen where Code = f.NomenCode and ProducerId = f.ParentId)Если ошибка осталась -- значит первый вариант, если пропала -- второй. |
13 ноя 12, 11:22 [13463363] Ответить | Цитировать Сообщить модератору |
Тэй Member Откуда: Сообщений: 79 |
Glory, что-то кеп и не кеп совсем. к какому? я ниже привожу запрос, к какому относится "строк обработано". выпадает именно тогда, когда начинается вставка.
ну и снова. посмотрите запрос, там как раз SELECT NomenCode, ParentId FROM tempNomen EXCEPT SELECT Code, ProducerId FROM Nomen разве вы не это же имели в виду? |
||
13 ноя 12, 11:23 [13463377] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Все форумы / Microsoft SQL Server | ![]() |