# Recursive CTE's



## Kirby.exe (17. Mai 2021)

Also ich sitze gerade an einer Aufgabe wo ich ein Dateisystem modellieren soll.

Nun soll ich mit einer recursive CTE einen Pfad von Dateien ausgeben und bekomme wieder Fehlermeldung die sehr weird sind 

Das ist mein bisheriger Code:

```
WITH RECURSIVE paths as (
    SELECT d1.parent_dir, '' From dirs d1 Where d1.inode = 0
    UNION ALL
    SELECT d.parent_dir, d.dir_name FROM paths, dirs d Where current.parent_dir <> 0 and d.inode = paths.parent_dir
)
```

Das ist die Fehlermeldung:


```
Fehler in der SQL-Abfrage (7): ERROR: syntax error at end of input
LINE 7: )
```

Die Create Tables and Inserts sind diese:

```
CREATE TABLE dirs(
    inode INTEGER PRIMARY KEY,
    dir_name VARCHAR(7) NOT NULL Check(dir_name <> '' or inode = 0),
    parent_dir INTEGER REFERENCES dirs,
    UNIQUE(dir_name, parent_dir)
);

-- Aufgabe 2)

CREATE TABLE files(
    inode INTEGER PRIMARY KEY,
    name_file VARCHAR(11) NOT NULL Check(name_file <> ''),
    parent_dir INTEGER REFERENCES dirs,
    content VARCHAR(20) NOT NULL
);

INSERT INTO
    dirs
VALUES
    (0, '', 0), (10, 'boot', 0), (20, 'etc', 0), (30, 'var', 0),
    (40, 'psql', 20),(50, 'cache', 30), (60, 'log', 30), (70, 'httpd', 60);

INSERT INTO
    files
VALUES
    (10,'test1', 70, 'blablabla'),(20,'test2', 20, 'blablabla');
```


----------



## Kirby.exe (17. Mai 2021)

Edit: Nachdem ich das Semikolon nach dem With entfernt habe kommt folgender Fehler:

```
Fehler in der SQL-Abfrage (7): ERROR: recursive query "paths" column 2 has type text in non-recursive term but type character varying overall
LINE 4: SELECT d1.parent_dir, '' From dirs d1 Where d1.inode = 0
HINT: Cast the output of the non-recursive term to the correct type.
```


----------



## mihe7 (17. Mai 2021)

Hier mal in Oracle SQL (das decode is ein if-else: wenn paths.dn ist null, dann ..., sonst ... und das || die String-Verkettung. Der Spaß ist in Oracle etwas schwieriger zu schreiben, weil dort der leere String und NULL gleich sind).

```
WITH paths(i, p, dn) AS (
    SELECT inode, parent_dir, dir_name FROM dirs where inode = 0
    UNION ALL
    SELECT d.inode, d.parent_dir, decode(paths.dn, NULL, '/' || d.dir_name, paths.dn || '/' || d.dir_name)
      FROM paths, dirs d 
     WHERE paths.i = d.parent_dir AND d.inode > 0
)
SELECT dn FROM paths;
```


----------

