|
Как в таблицу MS SQL добавить строки с ключевым полем без автоинкремента? | ☑ | ||
---|---|---|---|---|
0
MaxS
31.05.16
✎
16:16
|
Как побороть такую ошибку при попытке добавить строки в таблицу MS SQL? Интересует вариант не требующий внесения изменений в БД.
Поле MYNO - это первичный ключ. Не удалось вставить значение NULL в столбец "MYNO", таблицы "master.dbo.MYTAB"; в столбце запрещены значения NULL. Ошибка в UPDATE. Выполнение данной инструкции было прервано. |
|||
1
Господин ПЖ
31.05.16
✎
16:18
|
>в столбце запрещены значения NULL
что не ясного |
|||
2
Господин ПЖ
31.05.16
✎
16:18
|
+
Поле MYNO - это первичный ключ. |
|||
3
MaxS
31.05.16
✎
16:20
|
(1) Это ясно, но не хочется заниматься вычислением уникального значения, т.к. добавление происходит только тех записей, которых нет во временной таблице и всё это делается одним обращением к серверу.
Хочется чтобы оно само заполнялось )) |
|||
4
trad
31.05.16
✎
16:26
|
тип какой?
|
|||
5
trad
31.05.16
✎
16:28
|
и полуОфф
ты уверен что нужно напрямую трогать таблицы из master? |
|||
6
ДенисЧ
31.05.16
✎
16:28
|
set identityinsert off и вставлять свои поля
|
|||
7
trad
31.05.16
✎
16:29
|
(6) поле итак "без автоинкремента"
|
|||
8
MaxS
31.05.16
✎
16:30
|
(4) decimal(10,0) not null
(5) да я и не трогал мастер, это QA такое выдал в запросе обращение к dbo.MYTAB. |
|||
9
trad
31.05.16
✎
16:31
|
(8) "это QA такое выдал"
интересное кино |
|||
10
trad
31.05.16
✎
16:34
|
insert into mytab
select max(myno)+1, /*значение других полей*/ from mytab |
|||
11
MaxS
31.05.16
✎
16:38
|
(9) sql server management studio если быт точнее ))
(10) Это для добавления одной записи? А как сотню - другую? |
|||
12
MaxS
31.05.16
✎
16:41
|
За основу был взят этот запрос из одной конфигурации из открытых источников. ;)
У меня почти такое же формируется программно для других таблиц и полей. 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
MaxS
31.05.16
✎
16:43
|
(12) последний UNION ALL там лишний, запрос руками сократил.
|
|||
14
trad
31.05.16
✎
16:44
|
(11) "Это для добавления одной записи? А как сотню - другую?"
сценарий может сильно зависеть от источника этой сотни записей |
|||
15
MaxS
31.05.16
✎
16:49
|
(14) источник - переменная с типом таблица значений в модуле 1С.
Всю её загружаю во временную таблицу в MS SQL. Уже переделал запрос выше, получаю в итоге временную таблицу с записями, которых нет в таблице MYTAB. с двумя колонками MYNO, где все значения NULL и допустим MYNAME с наименованием товара. |
|||
16
trad
31.05.16
✎
17:11
|
временную таблицу так же юнионом собираешь?
|
|||
17
MaxS
31.05.16
✎
17:21
|
(16) Уже нет.
SELECT * INTO #TempTable2 FROM #TempTable1 ... WHERE ... |
|||
18
MaxS
31.05.16
✎
17:25
|
Задача пока свелась к необходимости перенумеровать колонку временной таблицы. Или получить из этой таблицы результат запроса с последовательно нумерованной колонкой.
|
|||
19
MaxS
31.05.16
✎
17:50
|
(16) Вернее первую таблицу через UNION ALL, там нет колонки MYNO потом сравниваю с имеющимися данными и получаю временную таблицу с записями, которых нет в ИБ.
То самое поле MYNO появляется в #TempTable2 из таблицы с рабочими данными. |
|||
20
MaxS
31.05.16
✎
21:28
|
Странно, что никто не ответил. Как оказалось, это азы.
Как всегда сам спросил сам и ответил )) SELECT MYNO , MYNAME , ROW_NUMBER() over (order by MYNO ) + 400 as NN INTO #TempTable2 FROM ... Получаем колонку NN с числами 401, 402 и т.п. Где 400 - максимальный существующий номер. Если кроме нас никто не добавляет данные в эту таблицу, то можно спокойно добавлять с данными из колонки NN. |
|||
21
DrZombi
гуру
31.05.16
✎
21:48
|
(11) >>> Это для добавления одной записи? А как сотню - другую?
Смешно. Вы узко мыслите. На Скуле нет одной записи при таком запросе... И да тригер попробуй использовать, при создании новой записи :) (20) Спасибо, отстой... |
|||
22
Fram
31.05.16
✎
22:45
|
(21) ТС просил без изменений структуры БД.. так что на твой пост можно ответить твоими же словами :)
|
|||
23
MaxS
01.06.16
✎
05:34
|
(21) Раз сказали А, говорите и Б. Примерчик бы увидеть. Создать несколько записей во временной таблице и добавить их в таблицу в БД.
|
|||
24
MaxS
01.06.16
✎
06:58
|
Нашлось красивее решение - создать пустую временную таблицу с автоинкрементным полем и при добавлении туда строк с колонкой MYNAME, поле MYNO будет автоматически заполняться уникальными значениями.
CREATE TABLE #TempTable2 ( MYNO INT not null identity(400,1) PRIMARY KEY , MYNAME nvarchar(254) not null ) Пока непонятно как в одной конструкции TSQL вычислить максимальное значение MYNO+1 и передать в текст создания временной таблицы |
|||
25
Fram
01.06.16
✎
07:17
|
(24) Ну либо через переменную, либо прямо туда вместо 400 селект засунь. сам не пробовал, но должно получиться
|
|||
26
trad
01.06.16
✎
09:16
|
(24) да, неплохо
|
|||
27
trad
01.06.16
✎
09:18
|
только я не очень понял зачем весь этот огород со временными таблицами.
я бы перебирая ТЗ закинул записи в поштучно |
|||
28
MaxS
01.06.16
✎
09:34
|
(27) Допустим в SQL сотни тысяч строк, из 1С поступает сотня строк. Нужно найти те строки ТЗ из 1С, которые новые. Поэтому пришлось запихнуть ТЗ из 1С во временную таблицу, сравнить с БД и подготовить другую таблицу для записи в БД.
А дёргать по одной строке - мне такой вариант не нравится. Лучше долго запрягать и быстро долететь. |
|||
29
trad
01.06.16
✎
09:57
|
(28) как я понимаю сейчас такая схема:
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
MaxS
01.06.16
✎
10:30
|
(29) вариант с временными таблицами отлаживать проще, как мне показалось. ;) Видна вся таблица перед помещением в целевую.
|
|||
31
Fram
01.06.16
✎
17:24
|
кстати, насчет 1с -> sql.. а файловый доступ к одной папке у обоих серверов есть? если есть, тогда bulk insert будет более эффективен.
|
|||
32
MaxS
01.06.16
✎
18:24
|
(31) Может быть на будущее пригодится. Но решение готовится для нескольких клиентов. В первую очередь нужен не быдлокод и работающее решение. Потом если потребуется будет оптимизация.
А нельзя SQL серверу через соединение отдать файл, чтобы он положил его у себя во временную папку и вернул бы путь к файлу, остальное дело техники. ;) |
|||
33
Fram
01.06.16
✎
19:44
|
(32) напиши новый провайдер подключения к БД, который позволит провернуть такой трюк :)
как вариант ftp можно поднять рядом с sql, но вряд ли ты так будешь заморачиваться. хотя когда речь зайдет за сотни тысяч записей тогда может и захочешь заморочиться |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |