问:请问如何在SQL中生成数字?我见过其它的人使用DBA_OBJECTS作为一个“大”表来生成ROWNUM。但是对于使用数据字典视图来说,这看上去并不是一个合适的办法。 答:我很同意你的看法,使用数据字典视图仅仅生成数字是很不合适的,特别是当你的系统需要更多值而不是对象的时候。那么下面就来介绍一个我经常使用的方法,即使用一个分级查询来生成值: select rownum from dual connect by rownum <=10; ROWNUM ——R……
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
问:请问如何在SQL中生成数字?我见过其它的人使用DBA_OBJECTS作为一个“大”表来生成ROWNUM。但是对于使用数据字典视图来说,这看上去并不是一个合适的办法。
答:我很同意你的看法,使用数据字典视图仅仅生成数字是很不合适的,特别是当你的系统需要更多值而不是对象的时候。那么下面就来介绍一个我经常使用的方法,即使用一个分级查询来生成值:
select rownum from dual connect by rownum <=10; ROWNUM ---------- 1 2 3 4 5 6 7 8 9 10 10 rows selected. |
然后可以很轻松地通过内联视图添加到你的查询中:
-- generate lots of fake data SELECT 'CUSTOMER_' || row_num customer_name FROM (SELECT ROWNUM row_num FROM DUAL CONNECT BY ROWNUM <= 10); CUSTOMER_NAME ----------------- CUSTOMER_1 CUSTOMER_2 CUSTOMER_3 CUSTOMER_4 CUSTOMER_5 CUSTOMER_6 CUSTOMER_7 CUSTOMER_8 CUSTOMER_9 CUSTOMER_10 10 rows selected. |
注意我在内联视图中重命名了pseudocolumn ROWNUM,从而外部查询生成的ROWNUM就不会有任何疑义。
-- create types to support pipelined function CREATE OR REPLACE TYPE num_rec IS OBJECT (num INTEGER); / CREATE OR REPLACE TYPE num_tab IS TABLE OF num_rec; / -- generate sequential numbers -- given a starting value and total count CREATE OR REPLACE FUNCTION numgen( p_start IN INTEGER ,p_count IN INTEGER ) RETURN num_tab PIPELINED IS BEGIN FOR rec IN (SELECT num_rec(ROWNUM + p_start - 1) r FROM DUAL CONNECT BY ROWNUM <= p_count) LOOP PIPE ROW (rec.r); END LOOP; RETURN; END numgen; / -- generate data SELECT 'CUSTOMER_' || num customer_name FROM TABLE(numgen(10, 10)); CUSTOMER_NAME ----------------- CUSTOMER_10 CUSTOMER_11 CUSTOMER_12 CUSTOMER_13 CUSTOMER_14 CUSTOMER_15 CUSTOMER_16 CUSTOMER_17 CUSTOMER_18 CUSTOMER_19 10 rows selected. |
管道函数可是用来异步返回大数据集,你可能会不解为什么在函数中仅仅使用一个FOR循环?
-- alternate method using FOR loop CREATE OR REPLACE FUNCTION numgen2( p_start IN INTEGER ,p_count IN INTEGER ) RETURN num_tab PIPELINED IS BEGIN FOR i IN p_start .. p_start + p_count - 1 LOOP PIPE ROW (num_rec(i)); END LOOP; RETURN; END numgen2; / SELECT 'CUSTOMER_' || num customer_name FROM TABLE(numgen2(10, 10)); CUSTOMER_NAME ----------------- CUSTOMER_10 CUSTOMER_11 CUSTOMER_12 CUSTOMER_13 CUSTOMER_14 CUSTOMER_15 CUSTOMER_16 CUSTOMER_17 CUSTOMER_18 CUSTOMER_19 10 rows selected. |
你当然可以得到相同的结果,那么这个方法会比其它的快一些吗?那么我们来试一试百万级别的数据,来看看会发生什么:
SQL> set timing on SQL> BEGIN 2 FOR rec IN (SELECT num 3 FROM TABLE(numgen(1, 1000000))) LOOP 4 NULL; 5 END LOOP; 6 END; 7 / PL/SQL procedure successfully completed. Elapsed: 00:00:05.32 SQL> SQL> BEGIN 2 FOR rec IN (SELECT num 3 FROM TABLE(numgen2(1, 1000000))) LOOP 4 NULL; 5 END LOOP; 6 END; 7 / PL/SQL procedure successfully completed. Elapsed: 00:00:01.11 -- run twice to be sure SQL> BEGIN 2 FOR rec IN (SELECT num 3 FROM TABLE(numgen(1, 1000000))) LOOP 4 NULL; 5 END LOOP; 6 END; 7 / PL/SQL procedure successfully completed. Elapsed: 00:00:05.32 SQL> SQL> BEGIN 2 FOR rec IN (SELECT num 3 FROM TABLE(numgen2(1, 1000000))) LOOP 4 NULL; 5 END LOOP; 6 END; 7 / PL/SQL procedure successfully completed. Elapsed: 00:00:01.09 |
纯PL/SQL解决方案绝对要快上许多。
作者
翻译
相关推荐
-
Collaborate 18大会:了解甲骨文云数据库和应用的进展
在Collaborate 18大会即将举行时,我们会发现,甲骨文用户社区的技术变化会略高于平常水平。 由独立甲 […]
-
甲骨文自治数据库亮相 带来云计算新希望
早前甲骨文还不在云计算公司之列,而现在该公司正在迅速弥补其失去的时间。甲骨文的云计算核心是甲骨文自治数据库(O […]
-
Oracle TNS 错误:管理员旷日持久的战斗
TNS经常给IT管理员带来麻烦,而且很难定位。尤其是在Oracle数据库中。本文将介绍如何避免这些常见错误。
-
DBA支招:如何实现Oracle EBS 12.2.5升级
那些对于是否要将EBS进行升级持观望态度的Oracle数据库管理员们可以从一家研究公司获得一些启示。