Выборка из таблиц и хранимки

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Rash
Сообщения: 3
Зарегистрирован: 03 авг 2005, 13:45

Выборка из таблиц и хранимки

Сообщение Rash » 04 янв 2007, 15:36

Сервер FB 1.5.3. Имеются две таблицы:

Код: Выделить всё

CREATE TABLE FOLDERS (
    ID        INTEGER NOT NULL,
    NAME      VARCHAR(256) NOT NULL,
    PARENTID  INTEGER
);

CREATE TABLE FILES (
    FOLDERID  INTEGER NOT NULL,
    FILENAME  VARCHAR(256) NOT NULL
);
связаны один ко многим для иммитации файловой системы

Код: Выделить всё

ALTER TABLE FILES ADD CONSTRAINT FK_FILES FOREIGN KEY (FOLDERID) REFERENCES FOLDERS (ID)
Пример данных:

Таблица FOLDERS

Код: Выделить всё

1 А NULL
2 Б 1
3 В 2
Т.е. дерево из папок, "В" вложена в "Б", которая в свою очередь вложена в "А".

Таблица FILES

Код: Выделить всё

3 X
3 Y
2 Z
Т.е. файлы X и Y привязаны к папке В, а файл Z привязан к папке Б.

Имеется также хранимая процедура, возвращающая полный путь от указанной папке. Например от GETPARENTS(3) вернет A/Б/В.

Код: Выделить всё

CREATE PROCEDURE GETPARENTS (
    ID INTEGER)
RETURNS (
    FULLPATH VARCHAR(2048))
AS
declare variable did integer;
declare variable oid integer;
declare variable name varchar(256);
BEGIN 
 FULLPATH='';
  WHILE (:ID IS NOT NULL) DO
    BEGIN 
      SELECT F.ID, F.PARENTID, F.NAME
      FROM FOLDERS F
      WHERE F.ID = :ID
      INTO :DID, :OID, :NAME; 
      ID = :OID;
      FULLPATH = :NAME || '\' || FULLPATH;
    END
 SUSPEND;
END
Проблема: по некому условию выбрать файлы и их полные пути, желательно одним запросом. Т.е. нужно что-то вроде

Код: Выделить всё

select getparents(folders.id), filename from files inner join folders on folders.id=files.folderid where filename = 'A'
Этот вариант естественно не работает. Мастера, подскажите как грамотно это сделать? :?

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 04 янв 2007, 16:42

Код: Выделить всё

select (select * from getparents(files.folderid))as folder, filename from files  where filename = 'Z'

Rash
Сообщения: 3
Зарегистрирован: 03 авг 2005, 13:45

Сообщение Rash » 04 янв 2007, 17:23

Не работет такое на версии 1.5.3, говорит Invalid token. Dynamic SQL Error. SQL error code = -104. Token unknown - line 1, char 16. *.

При этом работает на FB2, спасибо большое! Если других способов нет, будем перезжать на FB2.

2All: Может есть еще какие-нибудь способы (для ветки FB1.5)

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 04 янв 2007, 17:47

Как вариант: засунуть имя файла тоже в процедуру.
Но так на все случаи жизни процедур не напасешься
Лучше всеже на 2 переехать при возможности.

Кузнецов Евгений
Сообщения: 144
Зарегистрирован: 16 фев 2006, 22:36

Сообщение Кузнецов Евгений » 04 янв 2007, 18:33

Добрый день!

Можно так:

Код: Выделить всё

select (select fullpath from getparents(files.folderid))as folder, filename from files  where filename = 'Z'
Посмотрите http://www.ibase.ru/develop.htm#prog в разделе Древовидные и иерархические структуры приводились и другие способы построения деревьев.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 янв 2007, 13:27

www.ibase.ru/devinfo/treedb.htm

хранить "папки" и "файлы" в разных таблицах imho криво. и несколько недальновидно. В разных файловых системах у файлов есть версии, могут быть "подфайлы", и т.д. С моей точки зрения файл и папка - структурно одно и то же. Кстати, это так и с точки зрения файловой системы :)

Ответить