Sybase ASE按等级

时间:2017-05-17 15:06:31

标签: sql sybase sybase-ase

我想生成0到9000000之间的数字。在Oracle中,我可以使用下面的代码。如何在Sybase ASE中执行此操作?

这是在Oracle中:

SELECT level  Num
FROM DUAL
CONNECT BY LEVEL  <= 9000000
ORDER BY Num;

如何在Sybase ASE中执行此操作?

我无法创建表并添加标识,因为我需要1到9000000之间的数字,因此表格会很复杂。有没有要执行此操作的查询?

3 个答案:

答案 0 :(得分:3)

在Sybase IQ中,有一个可用于生成数字的系统过程:sa_rowgenerator

你可以做到:

 SELECT row_num FROM sa_rowgenerator( 1, 9000000);

我根本不了解Sybase ASE,因此我搜索了它并发现此过程在ASE中不可用,但存在替代方案:

  

SQL Anywhere系统过程sa_rowgenerator,sa_split_list和   ASE不支持sa_conn_info。 ASE主数据库包含   一个表,spt_values,可用于选择a中的整数值   类似于sa_rowgenerator过程或SQL的方式   Anywhere的dbo.row_generator系统表。

来源:Migrating SQL Anywhere database applications to ASE

这个包含整数的表spt_values令人难以置信地没有记录。这就像鬼桌。

我建议您尝试一下:

select number 
FROM master.dbo.spt_values
WHERE number BETWEEN 0 AND 9000000

但是,如果您的数据库系统爆炸,我不负责; - )

答案 1 :(得分:1)

这可能对你有用,但需要一点时间(但你可以按部分做)。对不起,但我不知道这样做的最好方法,只有下面的文字:

select * from 
(select (t6.i*1000000 + t5.i*100000 + t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_value from
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t5,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t6) v
where selected_value between 1 and 200 --here you can change the interval ex.: between 201 and 1000
order by selected_value

例如,如果您需要数字直到99999,那么您不需要t6和t5(只是为了更好地解释)。 我跑到这里,花了一分多钟才完成,直到5百万。

答案 2 :(得分:1)

您是否可以提供一些详细信息,说明您计划使用这些900万(+1)数字的内容/方式?

如果唯一的目的是将一组数字发送回客户端,在我看来,让客户端应用程序生成9m数字会更有效率。

基于少数几个较小的表的笛卡尔积,使用单个查询生成一系列数字的方法有很多种(参见RMH的基础10示例),但所有这些解决方案都需要:

  • 首先,要在tempdb中构建整个笛卡儿产品
  • 然后,要整理的整个笛卡尔积(在内存和tempdb中)
  • 然后才将所需的号码发送回客户

无论您是要生成一小组数字(1到10)还是一大组数字(1到9,000,000),都需要相同“生成器”查询的开销。

显然,需要使用更好,更高效,更轻量级的方法来防止占用dataserver资源(例如,想象几个用户/应用程序试图生成9,000,000个数字......所有这些都使用大量的tempdb空间以及cpu资源... egad ...期待来自DBA的愤怒的电子邮件/电话!)。

另一个想法是使用循环结构来生成所需的数字......

declare @counter bigint, @max bigint
select @counter=0, @max=9000000
while @counter <= @max
begin
    select @counter
    select @counter=@counter+1
end

...虽然这将消除tempdb开销,但你仍然会耗费900万次的中等量的cpu资源。产生900万个1行结果集的开销可能会带来额外的性能损失,特别是您可能会在数据服务器和客户端应用程序之间看到过多的网络数据包。

虽然我们可以通过使最终结果看起来像单个结果集来减少网络数据包的数量,但这需要将上述循环结构转换为存储过程,确保定义了环回服务器,然后创建代理表引用说proc;然后,您将查询代理表以获取包含所需数字集的单个结果集。

当然,在这一点上,我们现在不得不跳过一些箍,只是为了让dataserver生成(以一种有效的方法)一系列数字作为单个结果集。

Sybase / ASE可能还有其他一些方法可以生成一系列数字(例如,创建/填充带有标识列的表),但所有这些都需要a)一些数据服务器资源或b)一些复杂的代码(例如,应用程序上下文函数,插件java代码)......做一些可能由客户端/前端应用程序更有效地处理的事情。