Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Добавление нескольких значений при помощи одного INSERT'a. / 19 сообщений из 19, страница 1 из 1
09.08.2001, 09:22
    #32011479
Alexandr Kindras
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Есть таблица с 1 полем (uid) типа varChar(30).
Ситуация такова, на входе процедуры список строковых значений разделенных запятой (в конкретном случае 100 значений).
Каким образом запихнуть эти значения в поле uid при помощи одного запроса INSERT (а не сотни разумеется ).

Кто что может сказать по этому поводу, это вообще возможно?

Если бы данные извлекались из другой таблицы, то это выглядело бы так:
INSERT INTO TestTable1 (uid) SELECT uid FROM TestTable2
...
Рейтинг: 0 / 0
09.08.2001, 09:33
    #32011480
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Если так уж нужно, чтобы команда INSERT только один раз присутсвовала в коде, то можно записать получаемую строку в текстовый файл (возможно с добавлением/заменой символов для разделения полей/записей) и использовать затем BULK INSERT.

Будет ли это быстрее и не возникнут ли какие-нибудь побочные вопросы - кто знает ?
...
Рейтинг: 0 / 0
09.08.2001, 09:39
    #32011482
Alexandr Kindras
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Этот вариант я уже обдумывал, боюсь что использование промежуточных файлов нежелательно и скорее всего невозможно (в моем случае). Но все равно спасибо. Может еще есть варианты?
...
Рейтинг: 0 / 0
09.08.2001, 09:52
    #32011485
Павел
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Ведь кто-то формирует список строковых значений? Так пусть вместо этого формирует таблицу-переменную.
...
Рейтинг: 0 / 0
09.08.2001, 09:58
    #32011486
Alexandr Kindras
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Список значений формируется в COM объекте, который при помощи ADO соединяется с базой и вызывает процедуру со списком значений в качестве параметра. А что такое таблица - переменная? Можно ли сформировать ее в программе, т.е. через MS SQL API. Разъясните плиз.
...
Рейтинг: 0 / 0
09.08.2001, 10:32
    #32011490
Максим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Сорри зачем сто инсертов, можно и один но в цикле
))
Можно таким макаром влить в промежуточную таблицу а оттуда одним инсертом в основнкую
...
Рейтинг: 0 / 0
09.08.2001, 10:50
    #32011492
Alexandr Kindras
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
А в чем смысл вливания данных в промежуточную таблицу, чтобы скучно не было? Мне просто надо максимально ускорить процесс добавления этих записей. Ну а насчет цикла это ты загнул ))
...
Рейтинг: 0 / 0
09.08.2001, 10:59
    #32011493
Alisa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
1 строка - 1 INSERT. 100 строк - 100 INSERT. (Если я правильно понял - надо добавить 100 строк)
...
Рейтинг: 0 / 0
09.08.2001, 11:01
    #32011494
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
В 2000 можно написать ф-цию:
CREATE FUNCTION StrToArray (@StrValue varchar(8000), @Delimiter varchar(10))
RETURNS @Array TABLE (ID int, IntValue int)
AS
BEGIN
DECLARE @StartLoc int, @EndLoc int, @Len int, @Val varchar(20), @ValNum int
IF LEN(@Delimiter) = 0 RETURN
SELECT @StartLoc = 1, @EndLoc = 1, @Len = LEN(@StrValue), @ValNum = 1
WHILE @Len > 0
BEGIN
SELECT @EndLoc = CHARINDEX(@Delimiter, @StrValue, @StartLoc)
IF @EndLoc = 0 SELECT @EndLoc = @Len + 1, @Len = 0
SELECT @Val = LTRIM(SUBSTRING(@StrValue, @StartLoc, @EndLoc - @StartLoc))
IF @Val <> ''
BEGIN
INSERT @Array (ID, IntValue) SELECT @ValNum, CAST(@Val as int)
END
SELECT @StartLoc = @EndLoc + LEN(@Delimiter), @ValNum = @ValNum + 1
END
RETURN
END
GO
...
Рейтинг: 0 / 0
09.08.2001, 11:12
    #32011499
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Давайте-ка все таки определимся
1. Вы получаете данные для добавления в таком виде, что не можете сразу их добавить в таблицу
2. Для разбора полученной строки придется использовать цикл (т.к. вариант с промежуточным текстовым файлом и BULK INSERT вам не подходит)
3. Раз цикл - значит на каждом шаге цикла нужно вставлять новую запись
4. Использование временной промежуточной таблицы может быть оправдано, т.к. в многопользовательской базе данных обновляемая основная таблица может быть к примеру заблокирована другим пользователем и соответсвенно ваша команда INSERT будет. Временная же таблица видна только вам и никем кроме вас блокироваться не будет. Т.е. теоритически 100 INSERT-ов в основную таблицу могут выполняться медленне, чем 100 INSERT-ов во временную таблицу и 1 INSERT в основную таблицу.
5. К тому же непонятно, должен ли передаваемый вам параметер добавляться как все 100 записей или можно будет добавить только 99, на 100-ой произойдет ошибка. Если получаемые данные должны добавляться целиком или не добавляться вообще, то придется применять транзакции. А держать открытую транзакцию в цикле из 100 шагов - это не есть хорошо.


Поправьте меня, если я где-то не прав.
...
Рейтинг: 0 / 0
09.08.2001, 12:03
    #32011508
Alexandr Kindras
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
To Alisa: После твоего ответа мне стало казаться что я в зазеркалье ))

To Glory:
0. Спасибо за желание помочь.
1. Вернее не бывает.
2. Тоже правильно.
3. Собственно это так сказать вариант по умолчанию не вставлять же в самом деле 100 строк INSERT ))), но хотелось решить это более красиво.
4. В принципе как я понял из документации, накладные расходы на создание таблицы-переменной тоже большие. И если при многократных INSERT сервер производит буферизацию, то прирост в производительности может быть очень маленьким. Блокировка в данном случае не играет роли, т.к. все запросы в базу выполняются с NOLOCK.
5.Полученные данные должны быть добавлены целиком, без какого либо анализа. Собственно сама таблица используется как вспомогательная и обрабатывается в те промежутки времени, когда сервер наименее загружен.

Т.е. формулировка того что собственно меня интересует - как можно быстрее запихнуть в таблицу 100 значений.
...
Рейтинг: 0 / 0
09.08.2001, 12:39
    #32011511
Максим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Насчет цикла шутка

А вот насчет временной таблицы кроме преимуществ указанных Glory можешь получить + плюс по скорости при наличии в осноной таблице индексов. Да и появляется возможность обработки промежуточных данных.
...
Рейтинг: 0 / 0
09.08.2001, 13:18
    #32011516
Genady
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Навеяно SergSuper-ом
Create table table1 (string varchar(10))
Create table table2 (Number int)
insert into table2 values(1)
insert into table2 values(11)
insert into table2 values(21)
insert into table2 values(31)
insert into table2 values(41)
insert into table2 values(51)
insert into table2 values(61)
insert into table2 values(71)
insert into table2 values(81)
insert into table2 values(91)

declare @v varchar(100)
set @v='1111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000'

insert into table1 select substring(@v, Number, 10) from table2

select * from Table1
...
Рейтинг: 0 / 0
09.08.2001, 13:21
    #32011518
Genady
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Забыл дописать, понятное дело позиции должны быть фиксированы.
...
Рейтинг: 0 / 0
09.08.2001, 16:13
    #32011527
Павел
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Ну вот, самое интересное пропустил... Тем не менее

>Список значений формируется в COM объекте, который при помощи ADO соединяется с базой и вызывает процедуру со списком значений в качестве параметра. А что такое таблица - переменная? Можно ли сформировать ее в программе, т.е. через MS SQL API. Разъясните плиз.

Что такое таблица - переменная Вы наверное уже разобрались. Но это только в 2K. А в остальном это аналог временной таблицы, но В ПАМЯТИ. Так что накладные расходы по ее созданию куда меньше, чем по созданию #Table (последняя в любом случае физическая структура на диске). Обьявляется @Table как переменная, так что с API проблем никаких. Ворпос в другом - что важнее - быстро сформировать данные для вставки или быстро их вставить? Естно COM самостоятельно во много раз быстрее соберет строку, чем создаст @table на сервере и запихает туда данные. Уточните.
...
Рейтинг: 0 / 0
10.08.2001, 09:02
    #32011574
Alexandr Kindras
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Ок, спасибо всем кто принял участие в обсуждении этой проблемы. В особенности Павлу и Glory.
Итак в варианте для SQL2k я остановился на варианте фомирования таблицы-переменной (в теле процедуры) + UDF "List2Array", код приведен ниже.
-------- List2Array -------
CREATE FUNCTION List2Array (@StrValue varchar(4096), @Delimiter varchar(10) = ',')
RETURNS @Array TABLE (uid uniqueidentifier)
AS
BEGIN
DECLARE @StartLoc int, @EndLoc int
IF LEN(@StrValue) > 0 BEGIN
SET @StartLoc = 1
WHILE @EndLoc <> 0 BEGIN
SET @EndLoc = CHARINDEX(@Delimiter, @StrValue, @StartLoc)
IF @EndLoc <> 0
INSERT INTO @Array (UID) VALUES (CAST(LTRIM(RTRIM(SUBSTRING(@StrValue, @StartLoc, @EndLoc - @StartLoc))) As uniqueidentifier))
SET @StartLoc = @EndLoc + LEN(@Delimiter)
END
END
RETURN
END
---------------------------
А в 7-м пришлось идти банальным путем, т.е. просто запихнуть значения в цикле.
Посему есть еще одна причина перейти на 2000
Реализация чего нибудь в самом COM обьекте не оправдана, т.к. он написан на Visual Basic и накладные расходы при вызовах SQL API будут несоизмеримо больше.
Ежели кто еще может что-то добавить - милости просим
...
Рейтинг: 0 / 0
20.08.2001, 15:36
    #32012277
VadimB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Для MSSQL2000 более проще и универсальнее все это можно через
sp_xml_preparedocument и FROM OPENXML
...
Рейтинг: 0 / 0
20.08.2001, 16:40
    #32012286
Alexander Chepack
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
А вот так:

insert into t (YourColumn)
select @Var01
union all select @Var02
union all select @Var03

Ну и так далее?
...
Рейтинг: 0 / 0
20.08.2001, 16:43
    #32012287
Alexander Chepack
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление нескольких значений при помощи одного INSERT'a.
Sorry - абсолютно не по делу ответил - просто не понял вопрос.
Хотя если вместо переменных использовать извлечение подстрок - может что-то можно и придумать...
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Добавление нескольких значений при помощи одного INSERT'a. / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]