Je veux écrire une requête SQL qui accepte une variable de liaison (disons: NUM) et dont le résultat consiste en une colonne &: NUM nombre de lignes, chaque ligne ayant son numéro. c'est-à-dire si nous passons: NUM à 7, le résultat devrait être:
VAL
====
1
2
3
4
5
6
7
Aucune requête de base de données ne doit exister dans la requête et aucun code PL/SQL ne doit être utilisé. c'est-à-dire que seul le double doit être utilisé dans la requête
Y'a-t-il une quelconque façon de réussir cela?
Vous pouvez utiliser:
WHERE ROWNUM <= :NUM
... mais la table doit contenir une ligne égale ou supérieure à la limite dans la variable bind. Ce lien présente diverses techniques de génération de numéros de ligne dans Oracle .
En utilisant CONNECT BY
, Oracle 10g +:
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= :NUM
Confirmé par monojohnny
que la variable bind peut être utilisée. Les tentatives d'exécution sur Oracle 9i, bien que la syntaxe CONNECT BY
soit prise en charge, entraînent une erreur ORA-01436.
La seule chose sur laquelle je ne suis pas à 100%, c'est si le CONNECT BY acceptera la limite de la variable bind.
Référence:
Essayez quelque chose comme:
SELECT 1 AS Val FROM dual
UNION ALL SELECT 2 FROM dual
UNION ALL SELECT 3 FROM dual
UNION ALL SELECT 4 FROM dual
UNION ALL SELECT 5 FROM dual
UNION ALL SELECT 6 FROM dual
UNION ALL SELECT 7 FROM dual;
C'est désordonné, mais ça fera l'affaire.
Édité: Ah - vous devez passer une variable pour vous dire à quelle hauteur aller ...
Alors que diriez-vous de quelque chose comme:
SELECT t1.Val + t2.Val * 2 + t3.Val * 4 + t4.Val * 8 AS Val
FROM
(
SELECT 0 AS Val FROM dual
UNION ALL SELECT 1 FROM dual
) AS t1,
(
SELECT 0 AS Val FROM dual
UNION ALL SELECT 1 FROM dual
) AS t2,
(
SELECT 0 AS Val FROM dual
UNION ALL SELECT 1 FROM dual
) AS t3,
(
SELECT 0 AS Val FROM dual
UNION ALL SELECT 1 FROM dual
) AS t4
WHERE t1.Val + t2.Val * 2 + t3.Val * 4 + t4.Val * 8 <= 7;
Ok ... retouche encore, maintenant avec WITH:
WiTH
A0 AS (SELECT 0 as N FROM DUAL UNION ALL SELECT 0 FROM DUAL),
A1 AS (SELECT 0 as N FROM A0, A0 AS B),
A2 AS (SELECT 0 as N FROM A1, A1 AS B),
A3 AS (SELECT 0 as N FROM A2, A2 AS B),
A4 AS (SELECT 0 as N FROM A3, A3 AS B),
A5 AS (SELECT 0 as N FROM A4, A4 AS B),
A6 AS (SELECT 0 as N FROM A5, A5 AS B),
Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY N) AS Val FROM A6)
SELECT *
FROM Nums
WHERE Val <= :NUM
;
Je n'ai pas trouvé cette réponse [assurez-vous que tous les votes vont dans le bon sens !!], c'est juste mes notes de test basées sur 'OMG Ponies' [qui ne savait pas si la méthode fonctionnerait avec une variable de liaison] ci-dessus pour référence:
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> var num_rows number
SQL> begin select 20 into :num_rows from dual;
2 end;
3 /
PL/SQL procedure successfully completed.
SQL> select level from dual
2 connect by level <=:num_rows;
LEVEL
----------
1
2
3
4
...
Requête sans se connecter par
WITH num(n) as(select 1 from dual union all
select n+1 from num where n <= :num_limit)
select * from num
Je marque ce wiki de communauté car il ne répond pas à votre exigence de ne pas avoir de table, mais l'une des premières choses que nous faisons lorsque nous installons une base de données consiste à créer un ensemble de tables à cette fin.
Ce faisant, nous réduisons considérablement la complexité et augmentons la rapidité d'un grand nombre de requêtes, au détriment de l'espace disque (minimal et économique).
Vous devriez réfléchir sérieusement à cela. Mis à part le maintien de la table de date, il ne nécessite pas beaucoup d’entretien.
Une autre méthode consiste à utiliser une expression de plage XQuery, par exemple:
select column_value from xmltable(:a||' to '||:b);
1
2
3
4
5
6
7
8
9
10
Cette solution est assez flexible, par exemple:
select column_value from xmltable('5 to 10, 15 to 20');
5
6
7
8
9
10
15
16
17
18
19
20
Une autre solution nécessiterait un peu de PL/SQL pour créer une fonction permettant de renvoyer une collection avec les lignes ... Pas aussi simple que l'approche select level from dual connect by level <= :b1
, mais elle est utile dans quelques situations:
1) Créez un type d'objet de table numérique (number_tbl, dans cet exemple):
create or replace type number_tbl as table of number;
2) Créez une fonction qui recevra le nombre de lignes à générer, puis renvoyez un objet number_tbl avec les résultats:
create or replace function get_rows( i_num_rows number ) return number_tbl as
t number_tbl := number_tbl();
begin
if i_num_rows < 1 then
return null;
end if;
t.extend( i_num_rows );
for i in 1..i_num_rows loop
t(i) := i;
end loop;
return t;
end get_rows;
3) sélectionnez votre fonction en utilisant la fonction table( ... )
pour transformer votre objet number_tbl en quelque chose de sélectionnable:
select * from table( cast ( get_rows( :b1 ) as number_tbl ) );
se connecter par est une telle chose merveilleuse. Il vous aide à générer plusieurs lignes avec un seul ensemble de données disponibles dans une table double. Cela peut vous aider à générer un très grand nombre de lignes pour vos données factices. Par exemple
insert into test select a.* from test1 a,(select * from dual connect by level <=100000) b;
ou tu peux faire quelque chose comme ça
Exemple 2: vous souhaitez imprimer un carré et un cube de nombres de 1 à 10.
SQL> select level "No", power(level,2) "Square", power(level,3) "Cube" from dual connect by level <= 10;
No Square Cube
---------- ---------- ----------
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
Vous pouvez donc le manipuler sous la forme de votre choix. Voici comment vous pouvez renvoyer plusieurs lignes de la double table. Références: http://www.oraclebin.com/2012/12/multipe-rows-from-dual-table.html