Страница 1 из 1

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

Добавлено: 04 янв 2007, 15:36
Rash
Сервер 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'
Этот вариант естественно не работает. Мастера, подскажите как грамотно это сделать? :?

Добавлено: 04 янв 2007, 16:42
mdfv

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

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

Добавлено: 04 янв 2007, 17:23
Rash
Не работет такое на версии 1.5.3, говорит Invalid token. Dynamic SQL Error. SQL error code = -104. Token unknown - line 1, char 16. *.

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

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

Добавлено: 04 янв 2007, 17:47
mdfv
Как вариант: засунуть имя файла тоже в процедуру.
Но так на все случаи жизни процедур не напасешься
Лучше всеже на 2 переехать при возможности.

Добавлено: 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 в разделе Древовидные и иерархические структуры приводились и другие способы построения деревьев.

Добавлено: 05 янв 2007, 13:27
kdv
www.ibase.ru/devinfo/treedb.htm

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