Форум: "Базы";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];
ВнизВопрос по переменной типа table Найти похожие ветки
← →
Ega23 © (2006-09-25 14:14) [0]Исходные данные:
0. MS SQL 2000
1. Есть Master-таблица с иерархической структурой:
Create Table ProtocolEventTypes (
PrtEveTypCod int,
ParPrtEveTypCod int, -- FK на PrtEveTypCod,
........
)
2. Есть Detail-таблица, один-к-одному на Master:
Create Table ProtocolEvents (
PrtEveCod int,
PrtEveTypCod int, -- FK на ProtocolEventTypes.PrtEveTypCod
........
)
Задача: на клиенте данные из ProtocolEventTypes находятся в дереве. Рядом грид с данными из ProtocolEvents.
Нужно, выбрав любой узел в дереве, получить в гриде выборку по всем записям из detail-таблицы для данного узла, а также для всех узлов-потомков.
Как я обычно реализовывал: либо в динамике при рекурсивном обходе создавал строку типа id in (.....) и передавал её как output-параметр в SP, либо создавал временную таблицу и вставлял в неё на очередном такте рекурсии нужные мне записи.
Недавно увидел проDeclare t table (x int)
Возникают вопросы: в каком контексте создаётся t? TempDB или текущая БД? Как её надо убивать? Какие могут быть "подводные камни" при таком объявлении таблицы?
← →
stone © (2006-09-25 14:25) [1]
> Возникают вопросы: в каком контексте создаётся t?
В контексте твоего скрипта, как и любая локальная переменная.
> TempDB или текущая БД?
Темп, все в темп...
> Как её надо убивать?
Никак, как и любую локальную переменную
> Какие могут быть "подводные камни" при таком объявлении
> таблицы?
Можешь с ней работать только в пределах скрипта, из дугих скриптов она не видима, как и любая локальная переменная
← →
Ega23 © (2006-09-25 14:29) [2]
> Можешь с ней работать только в пределах скрипта, из дугих
> скриптов она не видима, как и любая локальная переменная
Ага, понятно. А как мне её в ХП передать при рекурсивном вызове?
← →
stone © (2006-09-25 14:38) [3]
> Ega23 © (25.09.06 14:29) [2]
Боюсь, что никак, для этого у ХП должен быть входной параметр типа таблица, лично мне такие не известны.
← →
Ega23 © (2006-09-25 14:42) [4]Всё ясно, спасибо!
← →
Bless © (2006-09-25 16:18) [5]
> Ega23 © (25.09.06 14:29) [2]
>
> Ага, понятно. А как мне её в ХП передать при рекурсивном
> вызове?
Может не в тему, но все же: а заменить хп на функцию, возвращающую table не подойдет?
← →
stud © (2006-09-25 16:24) [6]Ega23 © (25.09.06 14:29) [2]
Ага, понятно. А как мне её в ХП передать при рекурсивном вызове?
а если попытаться использовать
insert into #ttt <а здесь выходные параметры процедуры>?
← →
Bless © (2006-09-25 16:29) [7]
> stud © (25.09.06 16:24) [6]
Ну пока автора нет, попробую предположить, что он, встретив упоминание о table, хочет рассмотреть ее именно в качестве альтернативы временным таблицам.
← →
clickmaker © (2006-09-25 16:29) [8]
> Ага, понятно. А как мне её в ХП передать при рекурсивном
> вызове?
A local temporary table created in a stored procedure is dropped automatically when the stored procedure completes. The table can be referenced by any nested stored procedures executed by the stored procedure that created the table. The table cannot be referenced by the process which called the stored procedure that created the table
т.е. если создать #ttt, то рекурсию к ней можно применить
← →
Bless © (2006-09-25 16:30) [9]>Какие могут быть "подводные камни" при таком объявлении таблицы?
Еще во временные таблицы нельзя делать INSERT.
← →
clickmaker © (2006-09-25 16:32) [10]
> Еще во временные таблицы нельзя делать INSERT
как это?
а зачем они тогда?
← →
Ega23 © (2006-09-25 16:35) [11]
> т.е. если создать #ttt, то рекурсию к ней можно применить
Так я в [0] же писал, что так и делал...
> Ну пока автора нет, попробую предположить, что он, встретив
> упоминание о table, хочет рассмотреть ее именно в качестве
> альтернативы временным таблицам.
>
Совершенно верно. Просто интересно стало - можно ли такую таблицу использовать в качестве альтернативы #ttt.
Просто иначе не совсем понятно - для чего такой тип данных есть. Ну разве что, чтобы #ttt дропнуть не забыть...
← →
Bless © (2006-09-25 16:36) [12]
> clickmaker © (25.09.06 16:32) [10]
>
>
> > Еще во временные таблицы нельзя делать INSERT
>
> как это?
> а зачем они тогда?
Действительно. Я неправ.
← →
Bless © (2006-09-25 16:37) [13]нельзя
INSERT INTO table_variable EXEC stored_procedure
SELECT select_list INTO table_variable statements
← →
Ega23 © (2006-09-25 16:43) [14]
> нельзя
> INSERT INTO table_variable EXEC stored_procedure
>
> SELECT select_list INTO table_variable statements
>
И опять ты не прав. Можно. Только её сначала создать надо. Причём с теми полями и типами данных и в том порядке, которые ХП возвращает:
Create Table #Temp_Points (
ObjID int not null,
ObjOwner int null,
ObjNam varchar(64) not null
default " ",
ObjLab varchar(64) not null
default " ",
ObjOrd int not null,
ObjMsk tinyint not null,
ObjNot varchar(255) null,
ObjStat int not null
default 0,
LogAddr int not null
default 0,
PhsAddr int not null,
LogObjMultLevFl int not null,
LogObjImg image null,
LogObjHint varchar(255) not null
default " ",
LogObjATCod int null,
LogObjGPCod int null,
CPDevID int null
);
Insert into #Temp_Points
exec S_RTTIProc @ActNam="OBJECTSBYCLSID.SEL", @CLSID=600;
← →
Bless © (2006-09-25 16:51) [15]
> Ega23 © (25.09.06 16:43) [14]
>
> И опять ты не прав. Можно.
В [9] опечатался, имелись ввиду table-переменные (ведь ты об их ограничениях спрашивал).
← →
Bless © (2006-09-25 16:52) [16]В смысле, в отличие от таблиц (временных или нет) в table-переменную нельзя делать
INSERT INTO table_variable EXEC stored_procedure
SELECT select_list INTO table_variable statements
← →
stone © (2006-09-25 16:52) [17]
> Bless © (25.09.06 16:37) [13]
> нельзя
> INSERT INTO table_variable EXEC stored_procedure
>
> SELECT select_list INTO table_variable statements
через Exec нельзя, а если exec обернуть в OPENROWSET, то можно
← →
stone © (2006-09-25 16:54) [18]declare @t table (field int)
insert into @t
SELECT a.*
FROM OPENROWSET("SQLOLEDB",
"DRIVER={SQL Server};SERVER=(LOCAL);UID=sa;PWD=MyPswd",
"exec Database.dbo.stored_procedure")
AS a
select * from @t
← →
clickmaker © (2006-09-25 16:55) [19]
> Так я в [0] же писал, что так и делал...
а, ну да...
кстати, у меня есть алгоритм обхода дерева без рекурсивных вызовов. Может пригодится.declare @Current_ID int
declare @TreeLevel int
declare @Stack table (Object_ID int null, TreeLevel int)
declare @Results table (Object_ID int null)
select @Current_ID = @Object_ID
select @TreeLevel = 1
insert into @Stack values (@Current_ID, @TreeLevel)
while @TreeLevel > 0 begin
if exists (select * from @Stack where TreeLevel = @TreeLevel) begin
select top 1 @Current_ID = Object_ID from @Stack where TreeLevel = @TreeLevel
insert into @Results (Object_ID) values (@Current_ID)
delete from @Stack where TreeLevel = @TreeLevel and Object_ID = @Current_ID
if @Type is not null
insert into @Stack
select Object_ID, @TreeLevel + 1
from Objects
where Parent_ID = @Current_ID
else
insert into @Stack
select Object_ID, @TreeLevel + 1
from Objects
where Parent_ID = @Current_ID
if @@rowcount > 0
select @TreeLevel = @TreeLevel + 1
end
else
select @TreeLevel = @TreeLevel - 1
end
delete from @Results where Object_ID = @Object_ID
структура таблицы, думаю очевидна: Object_ID, Parent_ID
← →
Ega23 © (2006-09-25 16:56) [20]
> В [9] опечатался, имелись ввиду table-переменные (ведь ты
> об их ограничениях спрашивал).
А, тады сорри.
> stone © (25.09.06 16:54) [18]
Вах! Действительно можно.
Остаётся открытым вопрос: а нахрена так изголяться? :о)
← →
Ega23 © (2006-09-25 16:57) [21]
> clickmaker © (25.09.06 16:55) [19]
УХ ТЫ!!!
А вот за это - ОФИГЕННОЕ СПАСИБО!!!
← →
stone © (2006-09-25 17:01) [22]
> Остаётся открытым вопрос: а нахрена так изголяться? :о)
Незачем :)
Все должно использоваться там, где предназначено, только и всего. Эти таблицы действительно не надо дропать, поэтому в каких-то случаях они более удобны. Также они не видны из других процедур в пределах одного коннекта, за счет чего можно исключить конфликт имен в определенных случаях. Но совать их везде конечно не стоит :)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.038 c