我想编写一个接受绑定变量(例如:NUM)的SQL查询,其输出包含一列& :NUM行数,每行具有行号。即如果我们传递:NUM为7,则输出应为:
VAL
====
1
2
3
4
5
6
7
查询中不应该有任何实际的DB表,也不应该使用PL / SQL代码。即在查询中只应使用双重
有没有办法实现这个目标?
答案 0 :(得分:34)
您可以使用:
WHERE ROWNUM <= :NUM
...但是该表必须包含与bind变量中的限制相等或更大的行。 This link demonstrates various row number generation techniques in Oracle
使用CONNECT BY
,Oracle 10g +:
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= :NUM
由monojohnny
确认可以使用绑定变量。虽然支持CONNECT BY
语法,但尝试在Oracle 9i上运行会导致ORA-01436错误。
我唯一不能100%开启的是CONNECT BY是否接受绑定变量的限制。
参考:
答案 1 :(得分:4)
尝试类似:
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;
它很乱,但它会起作用。
编辑:啊 - 你需要传递一个变量来让你知道要走多远......
那么如下:
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;
好的...再次编辑,现在使用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
;
答案 2 :(得分:3)
我没有提出这个答案[所以确保任何选票都是正确的!!],它只是我的测试笔记基于'OMG小马'[谁不确定该方法是否适用于绑定变量]以上参考:
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
...
答案 3 :(得分:2)
无连接查询
WITH num(n) as(select 1 from dual union all
select n+1 from num where n <= :num_limit)
select * from num
答案 4 :(得分:0)
我正在标记这个社区维基,因为它实际上并没有满足你对没有表的要求,但是我们在安装数据库时首先要做的就是为这种目的创建一组表。
通过这样做,我们以(最小和最便宜的)磁盘空间为代价,大大降低了大量查询的复杂性并提高了速度。
你应该认真考虑一下。除了维护日期表外,还不需要很多维护。
答案 5 :(得分:0)
另一个解决方案需要一些PL / SQL来创建一个函数来返回带有行的集合......不像select level from dual connect by level <= :b1
方法那么简单,但它在以下几种情况下很有用:
1)创建一个数字表对象类型(在本例中为number_tbl):
create or replace type number_tbl as table of number;
2)创建一个函数,它将接收要生成的行数,然后返回一个带有结果的number_tbl对象:
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)使用table( ... )
函数从您的函数中选择将number_tbl对象转换为可选择的对象:
select * from table( cast ( get_rows( :b1 ) as number_tbl ) );
答案 6 :(得分:0)
insert into test select a.* from test1 a,(select * from dual connect by level <=100000) b;
或者你可以做这样的事情
示例2:您希望打印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
因此,您可以以任何您想要的形式操纵它。这是您可以从双表中返回多行的方法。 参考文献:http://www.oraclebin.com/2012/12/multipe-rows-from-dual-table.html
答案 7 :(得分:0)
另一种方法是使用XQuery范围表达式,例如:
select column_value from xmltable(:a||' to '||:b);
1
2
3
4
5
6
7
8
9
10
此解决方案非常灵活,例如:
select column_value from xmltable('5 to 10, 15 to 20');
5
6
7
8
9
10
15
16
17
18
19
20
答案 8 :(得分:0)
WITH cte_numbers(n)
AS (
SELECT 0
UNION ALL
SELECT n + 1
FROM cte_numbers
WHERE n < 10
)
SELECT n
FROM cte_numbers;
返回的行 0 1个 2 3 4 5 6 7 8 9 10
答案 9 :(得分:-1)