Informix не поддерживает предложение WITH, а тем более WITH RECURSIVE.Это делает эти подходы неработоспособными.Нет особо чистого способа сделать это.Не совсем ясно, что должно произойти, если у вас есть два или три списка, и не совсем ясно, имеете ли вы дело с простыми списками (пример - список) или с более общей древовидной структурой.
Однако,Вы можете создать временную таблицу и заполнить ее циклом в хранимой процедуре, а затем выбрать из временной таблицы в соответствующем порядке.Это сложнее, чем ужасно сложно.Вы делаете поиск таблицы в ширину.Я отмечаю, что вы не дали своей таблице имя - поэтому в дальнейшем она называется «анонимная».
CREATE TEMP TABLE Flattened
(
Hierarchy SERIAL,
Level INTEGER,
Name VARCHAR(25),
Value INTEGER,
Predecessor VARCHAR(25)
);
CREATE TEMP TABLE Intermediate
(
Hierarchy SERIAL,
Level INTEGER,
Name VARCHAR(25),
Value INTEGER,
Predecessor VARCHAR(25)
);
INSERT INTO Flattened(Hierarchy, Level, Name, Value, Predecessor)
SELECT 0, 0, name, value, predecessor
FROM Anonymous
WHERE Predecessor IS NULL;
WHILE ...any rows were inserted into table...
INSERT INTO Intermediate(Hierarchy, Level, Name, Value, Predecessor)
SELECT F.Hierarchy, F.Level + 1, A.Name, A.Value, A.Predecessor
FROM Flattened AS F, Anonymous AS A
WHERE F.Name = A.Predecessor
AND F.Level = (SELECT MAX(Level) FROM Flattened);
INSERT INTO Flattened SELECT * FROM Intermediate;
DELETE FROM Intermediate;
END WHILE
DROP TABLE Intermediate;
Теперь вы можете использовать:
SELECT Name, Value, Predecessor
FROM Flattened
ORDER BY Hierarchy, Level, Name;
Единственный остаточный хитрый битвыяснить, сколько строк было вставлено.В хранимой процедуре это, вероятно, проще всего сделать:
SELECT COUNT(*) INTO n_count FROM Flattened;
и
LET o_count = n_count - 1;
WHILE o_count != n_count
...as above - two INSERT operations and a DELETE operation
LET o_count = n_count;
SELECT COUNT(*) INTO n_count FROM Flattened;
END WHILE;
Собрав все это вместе, это работает для меня (в зарегистрированной базе данных).
BEGIN;
CREATE TABLE Anonymous
(
Name VARCHAR(25),
Value INTEGER,
Predecessor VARCHAR(25)
);
INSERT INTO Anonymous VALUES("buyingredients", 10, NULL);
INSERT INTO Anonymous VALUES("eat", 3, "cook");
INSERT INTO Anonymous VALUES("cook", 12, "mixingredients");
INSERT INTO Anonymous VALUES("mixingredients", 5, "buyingredients");
CREATE PROCEDURE Flatten_Anonymous()
DEFINE old_count INTEGER;
DEFINE new_count INTEGER;
CREATE TEMP TABLE Flattened
(
Hierarchy SERIAL,
Level INTEGER,
Name VARCHAR(25),
Value INTEGER,
Predecessor VARCHAR(25)
);
CREATE TEMP TABLE Intermediate
(
Hierarchy SERIAL,
Level INTEGER,
Name VARCHAR(25),
Value INTEGER,
Predecessor VARCHAR(25)
);
INSERT INTO Flattened(Hierarchy, Level, Name, Value, Predecessor)
SELECT 0, 0, name, value, predecessor
FROM Anonymous
WHERE Predecessor IS NULL;
SELECT COUNT(*) INTO new_count FROM Flattened;
LET old_count = new_count - 1;
WHILE old_count != new_count
INSERT INTO Intermediate(Hierarchy, Level, Name, Value, Predecessor)
SELECT F.Hierarchy, F.Level + 1, A.Name, A.Value, A.Predecessor
FROM Flattened AS F, Anonymous AS A
WHERE F.Name = A.Predecessor
AND F.Level = (SELECT MAX(Level) FROM Flattened);
INSERT INTO Flattened SELECT * FROM Intermediate;
DELETE FROM Intermediate;
LET old_count = new_count;
SELECT COUNT(*) INTO new_count FROM Flattened;
END WHILE
DROP TABLE Intermediate;
END PROCEDURE;
EXECUTE PROCEDURE Flatten_Anonymous();
SELECT Name, Value, Predecessor
FROM Flattened
ORDER BY Hierarchy, Level, Name;
DROP TABLE Flattened;
ROLLBACK;
Вывод:
buyingredients 10
mixingredients 5 buyingredients
cook 12 mixingredients
eat 3 cook
Тестовая платформа: Informix 11.70.FC2, работающий на MacOS X 10.6.7.
Формально не протестировано с несколькими независимыми иерархиямиили с древовидной иерархией вместо простых списков.