【问题标题】:Sybase ASE connect by level equivalentSybase ASE 按级别连接等效
【发布时间】:2017-10-17 03:18:03
【问题描述】:

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

这是在 Oracle 中:

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

如何在 Sybase ASE 中做到这一点?

我无法创建表格并添加身份,因为我需要从 1 到 9000000 的数字,所以表格会很复杂。有查询吗?

【问题讨论】:

  • 我的问题不清楚?

标签: sql sybase sap-ase


【解决方案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(只是为了更好地解释)。 我跑到这里,花了一多分钟才跑完,直到500万。

【讨论】:

    【解决方案2】:

    您能否详细说明您打算如何/如何使用这 900 万 (+1) 个数字?

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


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

    • 首先,要在 tempdb 中构建整个笛卡尔积
    • 然后,要对整个笛卡尔积进行排序(在内存和 tempdb 中)
    • 然后才将所需的数字发送回客户端

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

    显然,需要使用更好、更高效、轻量级的方法来避免占用数据服务器资源(例如,想象几个用户/应用程序试图生成 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 行结果集的开销,特别是您可能会看到在数据服务器和客户端应用程序之间流动的网络数据包数量过多。

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

    '当然,在这一点上,为了让数据服务器(以某种有效的方法)生成一系列数字作为单个结果集,我们现在不得不跳过几个环节。


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

    【讨论】:

      【解决方案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
      

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

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-10
      • 1970-01-01
      • 1970-01-01
      • 2015-09-10
      • 2023-03-09
      • 1970-01-01
      • 2013-09-14
      • 2018-06-07
      相关资源
      最近更新 更多