21.10.2013 Views

Firebird 2.1 Language Reference Update

Firebird 2.1 Language Reference Update

Firebird 2.1 Language Reference Update

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

DML statements<br />

for with my_rivers as (select * from rivers where owner = 'me')<br />

select name, length from my_rivers into :rname, :rlen<br />

do<br />

begin<br />

..<br />

end<br />

Recursive CTEs<br />

A recursive (self-referencing) CTE is a UNION which must have at least one non-recursive member, called the<br />

anchor. The non-recursive member(s) must be placed before the recursive member(s). Recursive members are<br />

linked to each other and to their non-recursive neighbour by UNION ALL operators. The unions between nonrecursive<br />

members may be of any type.<br />

Recursive CTEs require the RECURSIVE keyword to be present right after WITH. Each recursive union member<br />

may reference itself only once, and it must do so in a FROM clause.<br />

A great benefit of recursive CTEs is that they use far less memory and CPU cycles than an equivalent recursive<br />

stored procedure.<br />

The execution pattern of a recursive CTE is as follows:<br />

• The engine begins execution from a non-recursive member.<br />

• For each row evaluated, it starts executing each recursive member one-by-one, using the current values from<br />

the outer row as parameters.<br />

• If the currently executing instance of a recursive member produces no rows, execution loops back one level<br />

and gets the next row from the outer result set.<br />

Example with a recursive CTE:<br />

with recursive<br />

dept_year_budget as (<br />

select fiscal_year,<br />

dept_no,<br />

sum(projected_budget) as budget<br />

from proj_dept_budget<br />

group by fiscal_year, dept_no<br />

),<br />

dept_tree as (<br />

select dept_no,<br />

head_dept,<br />

department,<br />

cast('' as varchar(255)) as indent<br />

from department<br />

where head_dept is null<br />

union all<br />

select d.dept_no,<br />

d.head_dept,<br />

d.department,<br />

h.indent || ' '<br />

from department d<br />

join dept_tree h on d.head_dept = h.dept_no<br />

)<br />

70

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!