views:

680

answers:

4
INSERT INTO files (fileUID, filename)
WITH fileUIDS(fileUID) AS
( VALUES(1) UNION ALL
  SELECT fileUID+1 FROM fileUIDS WHERE fileUID < 1000 )
SELECT fileUID,
       TRANSLATE ( CHAR(BIGINT(RAND() * 10000000000 )), 'abcdefgHij', '1234567890' )
FROM fileUIDS;
A: 

The WITH word is used to create a Common Table Expression (CTE). In this case, it's creating an inline table that the "select fileUID, ..." part is pulling data from.

Chris Lively
A: 
WITH x AS (...)

This will take the output of the ... and treat it as a table named x, temporarily.

WITH x AS (...)
SELECT * FROM x

This statement will essentially give you the exact same thing as the ... outputs but it will instead be referenced as the table x

Joe Philllips
A: 

It is creating CTE (Common Table Expression). This is a basically a table that you don't have to create, drop, or declare in anyway. It will be automatically deleted after the batch has ran.

Check out http://4guysfromrolla.com/webtech/071906-1.shtml for more info.

Mark Callison
+1  A: 

The WITH syntax is the same as using either a local temp table or inline view. To my knowledge, it's only supported in SQL Server (2005+, called Common Table Expressions) and Oracle (9i+, called Subquery Factoring). The intended use is for creating a basic view that is used (ie: joined to) multiple times in a single query.

Here's a typical example:

WITH example AS (
     SELECT q.question_id,
            t.tag_name
       FROM QUESTIONS q
       JOIN QUESTION_TAG_XREF qtf ON qtf.question_id = t.question_id
       JOIN TAGS t ON t.tag_id = qtf.tag_id)
SELECT t.title,
       e1.tag_name
  FROM QUESTIONS t
  JOIN example e1 ON e1.question_id = t.question_id

...which will return identical results if you use:

SELECT t.title,
       e1.tag_name
  FROM QUESTIONS t
  JOIN (SELECT q.question_id,
               t.tag_name
          FROM QUESTIONS q
          JOIN QUESTION_TAG_XREF qtf ON qtf.question_id = t.question_id
          JOIN TAGS t ON t.tag_id = qtf.tag_id) e1 ON e1.question_id = t.question_id

The example you provided:

WITH fileUIDS(fileUID) AS ( 
     VALUES(1) 
     UNION ALL
     SELECT t.fileUID+1 
       FROM fileUIDS t
      WHERE t.fileUID < 1000 )
INSERT INTO files 
    (fileUID, filename)
SELECT f.fileUID,
       TRANSLATE ( CHAR(BIGINT(RAND() * 10000000000 )), 'abcdefgHij', '1234567890' )
  FROM fileUIDS f;

...is a recursive one. It's starting at 1, generating 999 fileuids in total (it would be 1,000 if it had started at 0).

OMG Ponies
DB2 supports WITH. See page 510 of ftp://ftp.software.ibm.com/ps/products/db2/info/vr82/pdf/en_US/db2s1e81.pdf. Oracle does not support the recursive form of WITH until 11gR2. (They have had CONNECT BY to support recursion for quite awhile.)
Shannon Severance
@Shannon: Thx, didn't know about DB2. I prefer the CONNECT BY syntax - seeing it in CTEs looks like such a hack.
OMG Ponies