Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вставка по Top (1000) SQL 2012 / 11 сообщений из 11, страница 1 из 1
18.10.2019, 17:41
    #39878436
Гулин Федор
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Добрый день всем.

SQL 2012

Операция РАЗОВАЯ (конвертация данных)
в этот момент я буду один на БД

Надо разбить один инсерт из темп. таблицы ##RR2 на батчи
потому что целевая таблица реплицируется на кучу (> 20) филиалов
( в реальности таких таблиц будет 3-4 )

в ##RR2 скажем 1 000 000 записей
( без репликации это копейки <5 секунд )


Есть ли гарантия что в 1- м Select и во 2-м DELETE TOP будет одинаковый набор данных ???

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
WHILE 1=1
BEGIN 
	
	BEGIN TRAN 
		Insert into d3
			(  )
		SELECT  TOP (1000)
		
		FROM  ##RR2   
		
		SET @rc1 =  @@ROWCOUNT
		-- print @@TRANCOUNT
		
	COMMIT 	
	
	IF @rc1 = 0 BREAK ;
	
	DELETE TOP (1000)  FROM  ##RR2
	
	PRINT @i
	Set @i = @i + 1
END 	 



Если нет гаратнии

то Как воркарвунд ?
вставлять в ##RR2 - доп. поле счетчика Id1
и делать то же самое

Код: sql
1.
2.
SELECT  TOP (1000) ORDER BY  id1
DELETE TOP (1000)  FROM  ##RR2 ORDER BY  id1



или другой воркарунд проще ?
PK в таблице ##RR2 не очевиден ( т.е в каждом случае он м.б разным для разных таблиц )
...
Рейтинг: 0 / 0
18.10.2019, 17:42
    #39878438
Гулин Федор
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
зы добавлю что кусок кода я вроде как протестировал
несколько раз
и у меня вроде как все получается ок в 1-м варианте
но все равно меня смущает сей момент
потому и спрашиваю
...
Рейтинг: 0 / 0
18.10.2019, 17:56
    #39878448
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Гулин Федор,

гарантии даст только использование output предложение, по которому можно сохранить в таблицу список вставленных ключей и использовать эти ключи для удаления.
...
Рейтинг: 0 / 0
18.10.2019, 17:57
    #39878450
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Гулин Федор,

нет никакой гарантии.
ORDER BY - для SELECT.

Может так?
Код: sql
1.
2.
WITH T AS(SELECT TOP(1000) * FROM ##RR2 ORDER BY id1)
DELETE T;

По крайней мере порядок записей в SELECTе гарантируется, если поле сортировки уникально.
...
Рейтинг: 0 / 0
18.10.2019, 18:01
    #39878457
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Чего-то не понимаю. В названии темы - про INSERT, а в скрипте - DELETE ??
...
Рейтинг: 0 / 0
18.10.2019, 18:36
    #39878476
a_voronin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Гулин Федор,

По чему вы решили, что DELETE удалит именно те записи, которые вставил INSERT? Естественно нет такой гарантии

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
		Insert into d3
		(  )
		OUTPUT INSERTED.<ключ> INTO @Keys

		SELECT  TOP (1000)
		FROM  ##RR2   


		DELETE TOP (1000)  FROM  ##RR2
		WHERE <Ключ>  IN (SEELCT * FROM @Keys) -- лучше INNER JOIN 





Insert into d3( )
SELECT TOP (1000)
FROM ##RR2
...
Рейтинг: 0 / 0
18.10.2019, 18:37
    #39878477
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Гулин Федор,

Код: sql
1.
DELETE TOP (1000) FROM ##RR2 output deleted.field1, ..., deleted.fieldN into d3(...)
...
Рейтинг: 0 / 0
21.10.2019, 10:14
    #39879093
Гулин Федор
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Всем СПАСИБО
да буду делать правильно
в моем случае проще добавить id1 во временную таблицу

Код: sql
1.
2.
WITH T AS(SELECT TOP(1000) * FROM ##RR2 ORDER BY id1)
DELETE T;
...
Рейтинг: 0 / 0
21.10.2019, 13:17
    #39879280
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Гулин Федор,

сортировка заметно дороже использования OUTPUT, это не оптимальное решение. Можно использовать триггер после вставки. В таблице inserted получите список ключей, которые надо удалить из источника. При этом не потребуется временная таблица и размер пачки может задавать произвольно запросом и гарантируется целостность переноса.
...
Рейтинг: 0 / 0
21.10.2019, 14:18
    #39879330
Гулин Федор
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Владислав Колосов,
это разовая задача
в данном случае мин. затраты как раз с id1
Времен.таблица уже есть и там куча логики по ее созданию

зы м.б еще я мало output юзал мало - понимать да понимаю
+ я еще писал что там ПК НЕ очевиден ( в 4 случаях )
а тут я единообзрано вставил 4 куска и все
- а так бы пришлось жойнить по ПК - а поля то разные

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Alter Table  ##RR2 Add id1 int  identity ;

WHILE 1=1
BEGIN 

BEGIN TRAN 
Insert into 
		SELECT  TOP (1000)
		...
		FROM  ##RR2   
		ORDER BY id1 

SET @rc1 =  @@ROWCOUNT
		-- print @@TRANCOUNT
	COMMIT 	
	
	IF @rc1 = 0 BREAK ;		
WITH T1 AS( SELECT TOP(1000) * FROM ##RR2 ORDER BY id1 )
	DELETE T1;
END 	 
...
Рейтинг: 0 / 0
30.10.2019, 16:08
    #39883163
Артем Falcon
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка по Top (1000) SQL 2012
Гулин Федор,


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
/*
Кидал данные из table1(mssql) в table2(postgree) через Linkserver. Объем большой, требовалось кидать по небольшим пакетам, иначе ( если больше 40000 строк за раз) связь обрывалась.
Написал вот так
*/
declare @a table(id_pg_max int);
declare @b int;
declare @c table(id int);
set @b=10000;

--------------------------------------------------ЦИКЛ------------------------------------------------------------------

	WHILE 
		(select case when max(id) is null then 0 else max(id) end from table2) < (select max(id) from  table1) 
		
		BEGIN
							 ----------------------BREAK------------------------- созданная таблица, для  прерывание цикла
							 IF EXISTS (SELECT * FROM break_point WHERE point=1)	
							 BEGIN
							 BREAK;
							 END
							 ----------------------------------------------------			  

				insert into @a (id_pg_max)								----диапозон ID от @a
				select  case when max(id) is null then 0 else max(id)end +1 as id
				from  table2;
				
				insert into @c (id)										----диапозон ID до @с
				select case when max(id) is null then 0 else max(id) end+@b as id 
				from  table2;
						

				insert into table2		----вставка значений из диапозона от @a до @с
				(
					id, fam, im, ot
				)
				select												 
					id, fam, im, ot
				from test..table1 
				where id between (select * from @a) and  (select * from @c)
				order by id;

				delete from @a	--чищу переменную
				delete from @c	--чищу переменную

		END
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вставка по Top (1000) SQL 2012 / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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