Как в таблицу MS SQL добавить строки с ключевым полем без автоинкремента? #773521


#0 by MaxS
Как побороть такую ошибку при попытке добавить строки в таблицу MS SQL? Интересует вариант не требующий внесения изменений в БД. Поле MYNO - это первичный ключ. Не удалось вставить значение NULL в столбец "MYNO", таблицы "master.dbo.MYTAB"; в столбце запрещены значения NULL. Ошибка в UPDATE. Выполнение данной инструкции было прервано.
#1 by Господин ПЖ
>в столбце запрещены значения NULL что не ясного
#2 by Господин ПЖ
+ Поле MYNO - это первичный ключ.
#3 by MaxS
Это ясно, но не хочется заниматься вычислением уникального значения, т.к. добавление происходит только тех записей, которых нет во временной таблице и всё это делается одним обращением к серверу. Хочется чтобы оно само заполнялось ))
#4 by trad
тип какой?
#5 by trad
и полуОфф ты уверен что нужно напрямую трогать таблицы из master?
#6 by ДенисЧ
set identityinsert off и вставлять свои поля
#7 by trad
поле итак "без автоинкремента"
#8 by MaxS
decimal(10,0) not null да я и не трогал мастер, это QA такое выдал в запросе обращение к dbo.MYTAB.
#9 by trad
"это QA такое выдал" интересное кино
#10 by trad
insert into mytab select   max(myno)+1,   /*значение других полей*/ from mytab
#11 by MaxS
sql server management studio  если быт точнее )) Это для добавления одной записи? А как сотню - другую?
#12 by MaxS
За основу был взят этот запрос из одной конфигурации из открытых источников. ;) У меня почти такое же формируется программно для других таблиц и полей. SELECT     TempTable1.Deletion AS Deletion,     TempTable1.CONO AS CONO,     TempTable1.NAME AS NAME INTO #TempTable1 FROM (     SELECT         0 AS Deletion,         '00069    ' AS CONO,         'Жена Калинин Федор Якубович' AS NAME     UNION ALL     SELECT         0 AS Deletion,         '00070    ' AS CONO,         'Жена Маков Денис Георгиевич' AS NAME     UNION ALL ) AS TempTable1 ; MERGE INTO CU_COMP AS CU_COMP     USING (         SELECT             TempTable1.CONO AS CONO,             TempTable1.NAME AS NAME         FROM #TempTable1 AS TempTable1         WHERE TempTable1.Deletion = 0     ) AS TempTable1     ON TempTable1.NAME = CU_COMP.NAME     WHEN MATCHED THEN         UPDATE SET             CU_COMP.CONO = TempTable1.CONO     WHEN NOT MATCHED THEN         INSERT (CONO, NAME)             VALUES (                 TempTable1.CONO,                 TempTable1.NAME             ) ; DELETE CU_COMP FROM CU_COMP AS CU_COMP, #TempTable1 AS TempTable1 WHERE CU_COMP.NAME = TempTable1.NAME     AND TempTable1.Deletion = 1 ; DROP TABLE #TempTable1
#13 by MaxS
последний UNION ALL  там лишний, запрос руками сократил.
#14 by trad
"Это для добавления одной записи? А как сотню - другую?" сценарий может сильно зависеть от источника этой сотни записей
#15 by MaxS
источник - переменная с типом таблица значений в модуле 1С. Всю её загружаю во временную таблицу в MS SQL. Уже переделал запрос выше, получаю в итоге временную таблицу с записями, которых нет в таблице MYTAB. с двумя колонками MYNO, где все значения NULL и допустим MYNAME с наименованием товара.
#16 by trad
временную таблицу так же юнионом собираешь?
#17 by MaxS
Уже нет. SELECT * INTO #TempTable2 FROM #TempTable1 ... WHERE ...
#18 by MaxS
Задача пока свелась к необходимости перенумеровать колонку временной таблицы. Или получить из этой таблицы результат запроса с последовательно нумерованной колонкой.
#19 by MaxS
Вернее первую таблицу через UNION ALL, там нет колонки MYNO потом сравниваю с имеющимися данными и получаю временную таблицу с записями, которых нет в ИБ. То самое поле MYNO появляется в #TempTable2 из таблицы с рабочими данными.
#20 by MaxS
Странно, что никто не ответил. Как оказалось, это азы. Как всегда сам спросил сам и ответил )) SELECT     MYNO , MYNAME , ROW_NUMBER over (order by MYNO ) + 400 as NN INTO #TempTable2 FROM ... Получаем колонку NN с числами 401, 402 и т.п. Где 400 - максимальный существующий номер. Если кроме нас никто не добавляет данные в эту таблицу, то можно спокойно добавлять с данными из колонки NN.
#21 by DrZombi
>>> Это для добавления одной записи? А как сотню - другую? Смешно. Вы узко мыслите. На Скуле нет одной записи при таком запросе... И да тригер попробуй использовать, при создании новой записи :) Спасибо, отстой...
#22 by Fram
ТС просил без изменений структуры БД.. так что на твой пост можно ответить твоими же словами :)
#23 by MaxS
Раз сказали А, говорите и Б. Примерчик бы увидеть. Создать несколько записей во временной таблице и добавить их в таблицу в БД.
#24 by MaxS
Нашлось красивее решение - создать пустую временную таблицу с автоинкрементным полем и при добавлении туда строк с колонкой MYNAME, поле MYNO будет автоматически заполняться уникальными значениями. CREATE TABLE #TempTable2 ( MYNO INT not null identity(400,1) PRIMARY KEY , MYNAME    nvarchar not null ) Пока непонятно как в одной конструкции TSQL вычислить максимальное значение MYNO+1 и передать в текст создания временной таблицы
#25 by Fram
Ну либо через переменную, либо прямо туда вместо 400 селект засунь. сам не пробовал, но должно получиться
#26 by trad
да, неплохо
#27 by trad
только я не очень понял зачем весь этот огород со временными таблицами. я бы перебирая ТЗ закинул записи в поштучно
#28 by MaxS
Допустим в SQL сотни тысяч строк, из 1С поступает сотня строк. Нужно найти те строки ТЗ из 1С, которые новые. Поэтому пришлось запихнуть ТЗ из 1С во временную таблицу, сравнить с БД и подготовить другую таблицу для записи в БД. А дёргать по одной строке - мне такой вариант не нравится. Лучше долго запрягать и быстро долететь.
#29 by trad
как я понимаю сейчас такая схема: 1. один запрос со 100 юнионами для вставки в темп1 2. соединение темп1 с целевой таблицей и получение темп2 3. вставка темп2 в целевую очень сильно сомневаюсь что это будет эффективнее, чем 100 раз по: if exists(select myno from mytab where ...) begin insert into mytab select max(myno)+1, ... end но как говорится: хозяин - барин
#30 by MaxS
вариант с временными таблицами отлаживать проще, как мне показалось. ;) Видна вся таблица перед помещением в целевую.
#31 by Fram
кстати, насчет 1с -> sql.. а файловый доступ к одной папке у обоих серверов есть? если есть, тогда bulk insert будет более эффективен.
#32 by MaxS
Может быть на будущее пригодится. Но решение готовится для нескольких клиентов. В первую очередь нужен не быдлокод и работающее решение. Потом если потребуется будет оптимизация. А нельзя SQL серверу через соединение отдать файл, чтобы он положил его у себя во временную папку и вернул бы путь к файлу, остальное дело техники. ;)
#33 by Fram
напиши новый провайдер подключения к БД, который позволит провернуть такой трюк :) как вариант ftp можно поднять рядом с sql, но вряд ли ты так будешь заморачиваться. хотя когда речь зайдет за сотни тысяч записей тогда может и захочешь заморочиться
Тэги: Админ
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С