Генерация хэш-таблиц
От: lebedkin  
Дата: 28.11.04 15:52
Оценка:
Люди, подскажите как разрешить следующий коленкор:
необходимо посредством хранимой процедуры возвратить выборку, типа хэш-таблицы. Поясняю, — имена полей должны браться динамически из одной таблицы, значения — из нескольких других. Пробовал сделать через тип TABLE (SQL Server 2000), но в этом случае ALTER TABLE не пашет, а следовательно поля в таблице можно добавить только на этапе определения (DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,)). Но соль в том, что имена полей выбираются из таблицы динамически, посему приходиться строить такую строку:
SET @SQL = 'DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,) INSERT INTO @TBL SELECT * FROM @TBL'.
Такая жуть разумеется работает, но SQL-строчка длиной более 8000 символов в EXEC() не обрабатывается.
Хотелось бы обойтись без временных таблиц.
Заранее благодарен.
Re: Генерация хэш-таблиц
От: Spidola Россия http://www.usametrics.ru
Дата: 29.11.04 01:18
Оценка:
Здравствуйте, lebedkin, Вы писали:

L>Люди, подскажите как разрешить следующий коленкор:

L>необходимо посредством хранимой процедуры возвратить выборку, типа хэш-таблицы. Поясняю, — имена полей должны браться динамически из одной таблицы, значения — из нескольких других. Пробовал сделать через тип TABLE (SQL Server 2000), но в этом случае ALTER TABLE не пашет, а следовательно поля в таблице можно добавить только на этапе определения (DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,)). Но соль в том, что имена полей выбираются из таблицы динамически, посему приходиться строить такую строку:
L>SET @SQL = 'DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,) INSERT INTO @TBL SELECT * FROM @TBL'.
L>Такая жуть разумеется работает, но SQL-строчка длиной более 8000 символов в EXEC() не обрабатывается.
L>Хотелось бы обойтись без временных таблиц.
L>Заранее благодарен.

Может посмотреть в сторону UDF (User Defined Functions)?
... << RSDN@Home 1.1.4 @@subversion >> Home
Re: Генерация хэш-таблиц
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.11.04 06:55
Оценка:
Здравствуйте, lebedkin, Вы писали:

L>Люди, подскажите как разрешить следующий коленкор:

L>необходимо посредством хранимой процедуры возвратить выборку, типа хэш-таблицы. Поясняю, — имена полей должны браться динамически из одной таблицы, значения — из нескольких других. Пробовал сделать через тип TABLE (SQL Server 2000), но в этом случае ALTER TABLE не пашет, а следовательно поля в таблице можно добавить только на этапе определения (DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,)). Но соль в том, что имена полей выбираются из таблицы динамически, посему приходиться строить такую строку:
L>SET @SQL = 'DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,) INSERT INTO @TBL SELECT * FROM @TBL'.
L>Такая жуть разумеется работает, но SQL-строчка длиной более 8000 символов в EXEC() не обрабатывается.
Обрабатывается. Можно конкатенировать параметр Exec:
Exec(@sql1+@sql2+@sql3)
Каждая из строк должна быть короче 8000, но сумма длин может быть любой.
L>Хотелось бы обойтись без временных таблиц.
А зачем тебе, собственно @tbl? Разве нельзя просто динамически построить select, который вернет то что надо?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Генерация хэш-таблиц
От: Аноним  
Дата: 29.11.04 08:21
Оценка:
Здравствуйте, Spidola, Вы писали:

S>Здравствуйте, lebedkin, Вы писали:


L>>Люди, подскажите как разрешить следующий коленкор:

L>>необходимо посредством хранимой процедуры возвратить выборку, типа хэш-таблицы. Поясняю, — имена полей должны браться динамически из одной таблицы, значения — из нескольких других. Пробовал сделать через тип TABLE (SQL Server 2000), но в этом случае ALTER TABLE не пашет, а следовательно поля в таблице можно добавить только на этапе определения (DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,)). Но соль в том, что имена полей выбираются из таблицы динамически, посему приходиться строить такую строку:
L>>SET @SQL = 'DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,) INSERT INTO @TBL SELECT * FROM @TBL'.
L>>Такая жуть разумеется работает, но SQL-строчка длиной более 8000 символов в EXEC() не обрабатывается.
L>>Хотелось бы обойтись без временных таблиц.
L>>Заранее благодарен.

S>Может посмотреть в сторону UDF (User Defined Functions)?


L>>Уже зыркал, пасибо.
Re[2]: Генерация хэш-таблиц
От: lebedkin  
Дата: 29.11.04 08:33
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, lebedkin, Вы писали:


L>>Люди, подскажите как разрешить следующий коленкор:

L>>необходимо посредством хранимой процедуры возвратить выборку, типа хэш-таблицы. Поясняю, — имена полей должны браться динамически из одной таблицы, значения — из нескольких других. Пробовал сделать через тип TABLE (SQL Server 2000), но в этом случае ALTER TABLE не пашет, а следовательно поля в таблице можно добавить только на этапе определения (DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,)). Но соль в том, что имена полей выбираются из таблицы динамически, посему приходиться строить такую строку:
L>>SET @SQL = 'DECLARE @TBL TABLE (Field1 int, Field2 nvarchar(10),..,) INSERT INTO @TBL SELECT * FROM @TBL'.
L>>Такая жуть разумеется работает, но SQL-строчка длиной более 8000 символов в EXEC() не обрабатывается.
S>Обрабатывается. Можно конкатенировать параметр Exec:
S>Exec(@sql1+@sql2+@sql3)

L>Пасибо, но это разумеется не выход.


L>Хотелось бы обойтись без временных таблиц.

S>А зачем тебе, собственно @tbl? Разве нельзя просто динамически построить select, который вернет то что надо?
Вернет-то может и то что надо, но мне нужна шапка для этого select, которая генерится динамически. Да, у меня там три вложенных курсора, — так что с select будет безумно тяжко.

Ладно, пасибо. Буду юзать временные таблицы сервера...
Re[3]: Генерация хэш-таблиц
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.11.04 08:44
Оценка:
Здравствуйте, lebedkin, Вы писали:

L>>Пасибо, но это разумеется не выход.

Почему?
L>>Хотелось бы обойтись без временных таблиц.
S>>А зачем тебе, собственно @tbl? Разве нельзя просто динамически построить select, который вернет то что надо?
L>Вернет-то может и то что надо, но мне нужна шапка для этого select, которая генерится динамически. Да, у меня там три вложенных курсора, — так что с select будет безумно тяжко.
Что такое "шапка для этого селект"? Еще раз: единственное, для чего могут быть необходимы временные таблицы — это нумерация строк (при помощи identity). Все остальное делается при помощи динамического построения select.
З.Ы. зачем тебе курсоры? Может,есть более простой способ обойти исходные данные? Курсоры плохи тем, что принудительно ограничивают свободу сервера по оптимизации запроса.
L>Ладно, пасибо. Буду юзать временные таблицы сервера...
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Генерация хэш-таблиц
От: _MarlboroMan_ Россия  
Дата: 29.11.04 09:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Еще раз: единственное, для чего могут быть необходимы временные таблицы — это нумерация строк (при помощи identity). Все остальное делается при помощи динамического построения select.


ну не скажи... развертка рекурсии в цикл на времянках — милое дело.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>

— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Re[5]: Генерация хэш-таблиц
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.11.04 09:44
Оценка:
Здравствуйте, _MarlboroMan_, Вы писали:

_MM_>ну не скажи... развертка рекурсии в цикл на времянках — милое дело.

Ах, ну да...
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Простите %)
От: Альт Россия http://cryptocode.ru
Дата: 30.11.04 02:25
Оценка:
Здравствуйте, _MarlboroMan_, Вы писали:

_MM_>ну не скажи... развертка рекурсии в цикл на времянках — милое дело.


"развертка рекурсии в цикл на времянках"... мне кажется, что это потерянный раздел камасутры
: 4000654
Re: Простите %)
От: _MarlboroMan_ Россия  
Дата: 30.11.04 04:25
Оценка:
Здравствуйте, Альт, Вы писали:

А>Здравствуйте, _MarlboroMan_, Вы писали:


_MM_>>ну не скажи... развертка рекурсии в цикл на времянках — милое дело.


А>"развертка рекурсии в цикл на времянках"... мне кажется, что это потерянный раздел камасутры


да нет, всё очень просто.

допустим есть у нас дерево tree(id int, parent_id int, <data>), и надо нам получить всех "потомков" для @ID. глубина дерева неизвестна.

вся рекурсия превращается в:

declare @id int
set @id = 

declare @level int
set @level = 0

declare @tmp table(id int, parent_id int, level int)

insert into @tmp (id, parent_id, level)
select id, parent_id, @level 
from tree 
where id = @id

while @@rowcount > 0
begin
    set @level = @level + 1

    insert into @tmp (id, parent_id, level)
    select tree.id, tree.parent_id, @level 
    from tree 
    inner join @tmp t on tree.main_id = t.parent_id and t.level = @level - 1
end

select * from @tmp
... << RSDN@Home 1.1.4 beta 3 rev. 185>>

— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Re: Простите %)
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.11.04 04:38
Оценка:
Здравствуйте, Альт, Вы писали:

А>"развертка рекурсии в цикл на времянках"... мне кажется, что это потерянный раздел камасутры

Увы, братан, увы На самом деле такая штука вполне существует.
Есть некоторые алгоритмы, которые в силу своей испорченности великолепно выражаются рекурсивно. Например, обход дерева или графа.
Так вот, разработчики MS SQL из принципиальных соображений ограничили глубину стека в T-SQL, что означает великий риск встрять при рекурсивных вызовах. Потому развертка рекурсивных алгоритмов в итеративные есть не камасутра, а самая что ни на есть насущная необходимость. Когда выйдет 2005, у нас появятся CTE из ANSI SQL-99, которые частично облегчат нашу участь. Но до того придется пользоваться временными таблицами, а то и курсорами иногда.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.