Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Можно ли обойтись без цикла?  [new]
ggarek
Member

Откуда:
Сообщений: 43
Есть две одинаковые таблицы в разных БД. Стоит задач объединения.
Нужно все записи из второй таблицы добавить к первой таблице. При переносе каждая запись получает новый id`шник, и нужно сохранить информацию о соответствии старого id`шника новому. То есть фактически нужно заполнить таблицу, состоящую из двух полей (new_id, old_id).
Сейчас я это делаю при помощи курсора в цикле, то есть обрабатываю последовательно каждую запись:

...
FETCH NEXT ..... FROM ... INTO @old_id
WHILE @@FETCH_STATUS = 0
BEGIN

INSERT INTO Table1
SELECT ,...,..,..,..,
FROM Table2

INSERT INTO Joint_table
                  (new_id, old_id)
VALUES        (SELECT id FROM Table1 WHERE id = @@IDENTITY), @old_id

FETCH NEXT ..... FROM ... INTO @old_id

END
...

Это очень долго. Подскажите, пожалуйста, как можно оптимизировать процесс!
4 июн 09, 16:40    [7266271]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
Змей
Member

Откуда: Н.Новгород -> Москва
Сообщений: 192
ggarek,

а на Table1 есть другие уникальные индексы кроме как по id?
4 июн 09, 16:53    [7266378]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
Возможно, автору поможет Предложение OUTPUT (Transact-SQL)
4 июн 09, 16:55    [7266395]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31172
ggarek
Это очень долго. Подскажите, пожалуйста, как можно оптимизировать процесс!
Если версия не меньше 2005, то используйте INSERT ... OUTPUT
4 июн 09, 16:56    [7266411]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
ggarek
Member

Откуда:
Сообщений: 43
Змей,

Нет, уникальный id один. Все остальные поле не identity.
4 июн 09, 17:02    [7266436]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
Змей
Member

Откуда: Н.Новгород -> Москва
Сообщений: 192
ggarek,

а просто добавить поле old_id в Table2 не проще будет?
4 июн 09, 17:49    [7266808]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
ggarek
Member

Откуда:
Сообщений: 43
Змей,

Нельзя, к сожалению =(
4 июн 09, 17:58    [7266887]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
Змей
Member

Откуда: Н.Новгород -> Москва
Сообщений: 192
ggarek,
а вот это, кстати, позабавило:)
(SELECT id FROM Table1 WHERE id = @@IDENTITY)
делать запрос, когда его результат и так ясен :) подсказать или сами догадаетесь? :)
4 июн 09, 18:13    [7266989]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
Змей
Member

Откуда: Н.Новгород -> Москва
Сообщений: 192
ggarek,

если еще актуально... если 2008-й, то можно без цикла.
где-то так:
use tempdb
go
if object_id('Table1', 'U') is null create table Table1 (id int identity(1,1), name varchar(10))
if object_id('LinkTable', 'U') is null create table LinkTable (old_id int, new_id int)
if object_id('Table2', 'U') is null create table Table2 (id int identity(1,1), name varchar(10))
go
truncate table dbo.Table1
truncate table dbo.Table2
truncate table dbo.LinkTable
go
insert Table1(name) values ('Коля'),('Оля'),('Толя')
insert Table2(name) values ('Саша'),('Маша'),('Даша')
go
---------------------------------------------------------------
MERGE 
INTO Table1 main 
USING Table2 secondary 
ON 1 = 0
    WHEN NOT MATCHED THEN INSERT(name) VALUES (secondary.Name)
OUTPUT
  secondary.id
, inserted.id
INTO LinkTable(old_id, new_id);
---------------------------------------------------------------
select * from Table1
select * from Table2
select * from LinkTable
---------------------------------------------------------------
go
/*
if object_id('Table1', 'U') is not null drop table Table1
if object_id('LinkTable', 'U') is not null drop table LinkTable
if object_id('Table2', 'U') is not null drop table Table2
go
*/
16 июн 09, 15:40    [7305723]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31172
Змей
ggarek,

если еще актуально... если 2008-й, то можно без цикла.
Без цикла уже для 2005 подсказали :-)
16 июн 09, 17:27    [7306544]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
Змей
Member

Откуда: Н.Новгород -> Москва
Сообщений: 192
alexeyvg
Змей
ggarek,

если еще актуально... если 2008-й, то можно без цикла.
Без цикла уже для 2005 подсказали :-)


Хм... Если вы про
insert ... output 
то можно примерчик?

сходу написал так:
insert Table1(name)
output inserted.id, Table2.id into LinkTable(new_id, old_id)
select 
    name 
from 
    Table2
но
msdn
<column_name> ::=
{ DELETED | INSERTED | from_table_name } . { * | column_name }
...........
from_table_name

Префикс столбца, который обозначает таблицу, содержащуюся в предложении FROM инструкции DELETE или UPDATE, и указывает обновляемые или удаляемые строки.


про INSERT ничего... а как тогда ?
16 июн 09, 19:23    [7307104]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31172
Змей
Хм... Если вы про
insert ... output 
то можно примерчик?

сходу написал так:
insert Table1(name)
output inserted.id, Table2.id into LinkTable(new_id, old_id)
select 
    name 
from 
    Table2
Всё правильно написали.
17 июн 09, 09:33    [7308235]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
Змей
Member

Откуда: Н.Новгород -> Москва
Сообщений: 192
alexeyvg
Всё правильно написали.

выполнять пробовали? у меня результат такой
автор
Msg 4104, Level 16, State 1, Line 2
The multi-part identifier "Table2.id" could not be bound.

Если покажете как можно вывести в OUTPUT при вставке чего-нибудь кроме как из inserted буду благодарен в БОЛе я примеров не нашел.
17 июн 09, 10:51    [7308700]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31172
Змей
alexeyvg
Всё правильно написали.

выполнять пробовали? у меня результат такой
автор
Msg 4104, Level 16, State 1, Line 2
The multi-part identifier "Table2.id" could not be bound.

Если покажете как можно вывести в OUTPUT при вставке чего-нибудь кроме как из inserted буду благодарен в БОЛе я примеров не нашел.
Да, поторопился :-(
17 июн 09, 15:21    [7310970]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли обойтись без цикла?  [new]
Daba
Member

Откуда:
Сообщений: 127
Сегодня столкнулся с такой же проблемой, и тоже упёрся :( .
Придумал одиозный способ:
1. всунуть результат с OUTPUT (новые ID) во временную таблицу #t, причем SELECT с OREDER BY old_id.
2. Получить @@rowcount
2. select TOP(@rowcount) new_id, old_id from #t cross join Table2 ORDER BY new_id, old_id

Если у кого есть что поумнее - поделитесь.
5 июл 09, 16:17    [7377965]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить