Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用oracle SQL查询在中生成字母表序列_Sql_Oracle_Plsql_Sequence - Fatal编程技术网

使用oracle SQL查询在中生成字母表序列

使用oracle SQL查询在中生成字母表序列,sql,oracle,plsql,sequence,Sql,Oracle,Plsql,Sequence,我有一个任务,每次执行相同的oracle查询时,我都必须生成字母序列 例如: 当我第一次执行查询时,它必须生成一个 当我第二次执行相同的查询时,它必须生成B 所以,它应该生成A,B,C,D……Z。一旦到达Z,它必须产生AA、AB、AC……AZ 如何组合查询?对序列使用字母表示法不是一个好主意,应该使用数值。Oracle为此提供了标识列 如果您确实需要一个字母序列,那么您可以创建一个简单的序列和一个函数,该函数返回您选择的字母序列。在函数中使用查询: CREATE SEQUENCE s; C

我有一个任务,每次执行相同的oracle查询时,我都必须生成字母序列

例如:

  • 当我第一次执行查询时,它必须生成一个
  • 当我第二次执行相同的查询时,它必须生成B
所以,它应该生成A,B,C,D……Z。一旦到达Z,它必须产生AA、AB、AC……AZ


如何组合查询?

对序列使用字母表示法不是一个好主意,应该使用数值。Oracle为此提供了
标识列

如果您确实需要一个字母序列,那么您可以创建一个简单的
序列
和一个
函数
,该函数返回您选择的字母序列。在函数中使用查询:

CREATE SEQUENCE s;

CREATE OR REPLACE FUNCTION get_alpha_seq (seq_val IN NUMBER)
RETURN VARCHAR2 AS
    v_val NUMBER;
    alpha_seq VARCHAR2(4000);
BEGIN
    v_val := seq_val;
    SELECT case when i3 > 0 then chr(i3+ascii('A')-1) end ||
           case when i2 > 0 then chr(i2+ascii('A')-1) end ||
           chr(i1+ascii('A')-1)
    INTO alpha_seq
      FROM (
    SELECT mod((v_val-1),27) i1,
           mod( trunc((v_val-0.1)/27), 27) i2,
               mod( trunc((v_val-0.1)/27/27), 27 ) i3,
              v_val l
     FROM dual
          )
    WHERE i1 <> 0
      AND NOT( l>= 27*27 and i2 = 0)
      AND NOT( l>= 27*27*27 and i3 = 0);

RETURN alpha_seq;
END;
/
演示:

类似地,它可以返回如下所示的字母顺序:

A
B
C
...
Z
AA
AB
...
AY
AZ
BA
BB
...
ZZ
AAA
AAB
...
ZZZ

为了确保仅此查询使用序列,我们可以使用下面的

  create table alpha_seq( t number);
  insert into alpha_seq values(0);
然后使用下面的函数

    CREATE OR REPLACE FUNCTION get_alpha_sequence 
    RETURN VARCHAR2 AS
    pragma autonomous_transaction;
        v_value NUMBER;
        alpha_seq VARCHAR2(4000);
    begin
    update alpha_seq set t=t+1;
    select t into v_value from alpha_seq;
    commit;
    with
     letters
     as
     (select chr( ascii('A')+level-1 ) letter
        from dual
      connect by level <= 26
     ),
     alpha as (select *
      from letters
      union all
     select l1.letter || l2.letter
      from letters l1, letters l2
     union all
      select l1.letter || l2.letter || l3.letter
      from letters l1, letters l2, letters l3)
      select letter into alpha_seq from (select a.*,rownum rw1 from alpha a
      where rownum <=v_value) where rw1=v_value;
      return alpha_seq;
      END;

. . SQL查询力求确定性。如果你想改变行为,你需要以某种方式对它们进行参数化,或者改变底层数据。可能是一个序列,然后将该数字转换成一个类似于模的字符串?谁给了你这样的“任务”?这完全没有道理。您可以利用这样的输出有什么可能的用途?为什么需要这个字母序列???@psaraj12我们使用这个序列来附加数值,同时生成一些发票数据,并在我们的一个存储过程中实现。这个解决方案可能比我现在看到的问题更多。首先,应该关闭缓存;否则,如果缓存的序列值没有用完,则会有间隙。这很容易解决。更难解决的问题:如何确保此查询和此查询只使用序列中的值,而noone和nothing使用序列中的值。在我看来,除了问题本身毫无意义之外,序列应该永远是纯整数,而不是字符。为了避免该功能,OP可以使用相同的逻辑。但是,顺序是必需的。有许多方法可以解决这些缺点。然而,我真的对使用字母序列而不是数字序列的要求提出了质疑。@mathguy关于如何确保此查询和此查询只使用字母序列,而noone和nothing使用序列中的值?那么,如果不能保证序列可以专用于应用程序中的特定进程,为什么还要有序列呢?这种控制在任何应用程序设计中都是必要的。Oracle在内部使用了很多sequence对象,所以您会问Oracle,如果他们的开发人员在另一个功能中使用相同的sequence,该怎么办?在基于面向对象编程的应用程序中,可以很容易地确保对象专用于特定的进程OK,那么如何确保没有其他查询(或INSERT语句等)使用相同序列中的值呢?当然,您发布的代码中没有任何东西可以保证这一点。如果您确实有一个建议的解决方案,而不是一般性的解决方案,这可能会对OP更有帮助。(请注意,无论在应用程序中执行什么操作,都必须在DB级别执行某些操作。否则,其他进程将能够访问序列。)@mathguy
sequence
是一个与其他数据库对象类似的对象。在数据库中创建的任何对象都是用于应用程序目的的。您是否将
SYS
拥有的对象用于常规用途?当然不是。您将如何限制某人不按顺序使用表?OP再次询问字母顺序,我回答了。如果我必须发布所有涉及的细微差别,那么它就不在这里的范围之内。感谢您的提问,保持安全:-)这是工作绝对好,并按照我的要求。非常感谢。如果答案能解决您的问题,请接受problem@psaraj12使用函数执行DML事务和提交是一个非常糟糕的主意。试想一下,
只读
用户仅仅为了读取数据而使用此功能会有多可怕?如果将表空间设置为只读,则根本无法使用此函数。这样做只会带来更多的问题。而且,在迁移期间处理这样的
UDF
也是一场噩梦。应该避免。此外,为序列维护另一个表的开销也是一种过度消耗。如果在ETL中使用此功能,则根本不可能对其进行维护。同样,应避免。根据OP,此序列用于生成发票数据,因此不存在以只读用户身份查询此信息的问题。@psaraj12是否可以实现此任务的下一个级别A000-A999、B000-B999。。。Z000-Z999,AA00-AA99,AB00-AB99。。。ZZ00-ZZ99?如果可能的话,请告诉我。
  create table alpha_seq( t number);
  insert into alpha_seq values(0);
    CREATE OR REPLACE FUNCTION get_alpha_sequence 
    RETURN VARCHAR2 AS
    pragma autonomous_transaction;
        v_value NUMBER;
        alpha_seq VARCHAR2(4000);
    begin
    update alpha_seq set t=t+1;
    select t into v_value from alpha_seq;
    commit;
    with
     letters
     as
     (select chr( ascii('A')+level-1 ) letter
        from dual
      connect by level <= 26
     ),
     alpha as (select *
      from letters
      union all
     select l1.letter || l2.letter
      from letters l1, letters l2
     union all
      select l1.letter || l2.letter || l3.letter
      from letters l1, letters l2, letters l3)
      select letter into alpha_seq from (select a.*,rownum rw1 from alpha a
      where rownum <=v_value) where rw1=v_value;
      return alpha_seq;
      END;
 select get_alpha_sequence from dual;

 A


 select get_alpha_sequence from dual;

 B