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;
Répondre
La syntaxe WITH est identique à l'utilisation d'une table temporaire locale ou d'une vue en ligne. À ma connaissance, il est uniquement pris en charge dans SQL Server (2005+, appelé Common Table Expressions) et Oracle (9i +, appelé sous-requête affacturage). L'utilisation prévue est pour créer une vue de base qui est utilisée (c'est-à-dire: jointe à) plusieurs fois dans une seule requête.
Voici un exemple typique:
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
... qui retournera des résultats identiques si vous utilisez:
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
L'exemple que vous avez fourni:
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;
... est un récursif. Il commence à 1, générant 999 fileuids au total (ce serait 1000 s'il avait commencé à 0).
DB2 prend en charge WITH. Voir page 510 de ftp://ftp.software.ibm.com/ps/products/db2/info/vr82/pdf/fr_FR/db2s1e81.pdf. Oracle ne supporte pas la forme récursive de WITH jusqu'à 11gR2. (Ils ont eu CONNECT BY pour supporter la récursion pendant un certain temps.) –
@Shannon: Thx, ne connaissait pas DB2. Je préfère la syntaxe CONNECT BY - la voir dans les CTE ressemble à un tel hack. –
Le mot WITH est utilisé pour créer une expression de table commune (CTE). Dans ce cas, il crée une table en ligne dans laquelle la partie "select fileUID, ..." extrait des données.
WITH x AS (...)
Cela prendra la sortie du ...
et le traiter comme une table nommée x
, temporairement.
WITH x AS (...)
SELECT * FROM x
Cette déclaration sera essentiellement vous donner exactement la même chose que les ...
sorties, mais il sera plutôt référencé la table x
Il crée CTE (expression commune tableau). Il s'agit essentiellement d'une table que vous n'avez pas besoin de créer, supprimer ou déclarer de toute façon. Il sera automatiquement supprimé après l'exécution du lot.
Consultez http://4guysfromrolla.com/webtech/071906-1.shtml pour plus d'informations.
BTW, sans rapport avec votre question à propos de WITH, en général, rand() retournera la même valeur pour une instruction SQL entière, peu importe combien de lignes sont retournées. Si vous voulez des valeurs différentes, alors: bouclez et appelez rand() à chaque itération, appelez rand avec une graine qui change par ligne (pas très aléatoire) ou utilisez NEWID ou NEW_ID, quel qu'il soit. Rechercher stackoverflow pour des exemples. –