|   |   | 
| 
 | Как в таблицу 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, но вряд ли ты так будешь заморачиваться. хотя когда речь зайдет за сотни тысяч записей тогда может и захочешь заморочиться | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |