Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.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
Sql 获取序列的最小值_Sql_Oracle_Oracle11g_Sequence - Fatal编程技术网

Sql 获取序列的最小值

Sql 获取序列的最小值,sql,oracle,oracle11g,sequence,Sql,Oracle,Oracle11g,Sequence,我在数据库中定义了大约100个序列,这些序列在测试完成后被设置为某个数字 例如: 有一个顺序:suppier_seq。 从1开始,现在它的电流是101 我需要根据最小值重置所有存在的序列 如果我提取序列的DDL,它的当前值如下所示: CREATE SEQUENCE "RMS14"."SUPPLIER_SEQUENCE" MINVALUE 0 MAXVALUE 99999999999 INCREMENT BY 1 START WITH 101 CACHE 100 NOORDER NOCYCL

我在数据库中定义了大约100个序列,这些序列在测试完成后被设置为某个数字

例如: 有一个顺序:suppier_seq。 从1开始,现在它的电流是101

我需要根据最小值重置所有存在的序列

如果我提取序列的DDL,它的当前值如下所示:

CREATE SEQUENCE  "RMS14"."SUPPLIER_SEQUENCE"  MINVALUE 0 MAXVALUE 99999999999 INCREMENT BY 1 START WITH 101 CACHE 100 NOORDER  NOCYCLE ;
我需要用最小值重新启动序列


如何通过SQL捕获序列的最小值?

您无法判断序列的原始值是什么。您只能基于
MINVALUE
,或者使用该值(即使为零),或者向其中添加一个值,或者仅在该值为非零时才这样做

您可以从
user\u sequences
视图中获取自己序列的当前值,并使用PL/SQL块循环它们,同时生成drop和create语句:

set serveroutput on
begin
  for r in (
    select 'DROP SEQUENCE "' || sequence_name || '"' as drop_stmt,
      'CREATE SEQUENCE "' || sequence_name || '"'
        || ' MINVALUE ' || min_value
        || ' MAXVALUE ' || max_value
        || ' INCREMENT BY ' || increment_by
        || ' START WITH ' || min_value
        || case when cache_size = 0 then ' NOCACHE' else ' CACHE ' || cache_size end
        || case when order_flag = 'Y' then ' ORDER' else ' NOORDER' end
        || case when cycle_flag = 'Y' then ' CYCLE' else ' NOCYCLE' end
        as create_stmt
    from user_sequences
  )
  loop
    dbms_output.put_line(r.drop_stmt);
--    execute immediate r.drop_stmt;
    dbms_output.put_line(r.create_stmt);
--    execute immediate r.create_stmt;
  end loop;
end;
/
我把
executeimmediate
语句注释掉了,以避免在没有任何检查的情况下复制和粘贴该语句时发生意外;最初,它只显示它将运行的命令,例如

PL/SQL procedure successfully completed.

DROP SEQUENCE "SUPPLIER_SEQUENCE"
CREATE SEQUENCE "SUPPLIER_SEQUENCE" MINVALUE 0 MAXVALUE 99999999999 INCREMENT BY 1 START WITH 0 CACHE 100 NOORDER NOCYCLE
...
如果您正在另一个架构中工作,并且具有正确的权限,则可以查询
all_sequences
dba_sequences
,并指定所有者:

    select 'DROP SEQUENCE "' || sequence_owner || '"."' || sequence_name ||'"' as drop_stmt,
      'CREATE SEQUENCE "' || sequence_owner || '"."' || sequence_name || '"'
        || ' MINVALUE ' || min_value
...
另一种方法是改变序列,将
增量设置为减去当前最高值(或最高值减去
MINVALUE
),调用
nextval
,然后重置增量。这在动态上有点混乱,主要是因为当直接在这样的循环中执行时,需要动态语句的第二级来获取当前序列值,但基本上是相同的想法:

declare
  l_nextval number;
begin
  for r in (
    select 'BEGIN EXECUTE IMMEDIATE ''ALTER SEQUENCE "' || sequence_name || '"'
        || ' INCREMENT BY -''|| ("' || sequence_name || '".nextval - ' || min_value ||'); END;'
        as alter_stmt_1,
      'SELECT "' || sequence_name || '".nextval from dual' as adjust_stmt,
      'ALTER SEQUENCE "' || sequence_name || '"'
        || ' INCREMENT BY ' || increment_by
        as alter_stmt_2
    from user_sequences
  )
  loop
    dbms_output.put_line(r.alter_stmt_1);
--    execute immediate r.alter_stmt_1;
    dbms_output.put_line(r.adjust_stmt);
--    execute immediate r.adjust_stmt into l_nextval;
    dbms_output.put_line(r.alter_stmt_2);
--    execute immediate r.alter_stmt_2;
  end loop;
end;
/

PL/SQL procedure successfully completed.

BEGIN EXECUTE IMMEDIATE 'ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY -'|| ("SUPPLIER_SEQUENCE".nextval - 0); END;
SELECT "SUPPLIER_SEQUENCE".nextval from dual
ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY 1
您还可以在循环中生成动态语句,这对于这种方法来说可能有点整洁:

declare
  l_alter_stmt_1 varchar2(4000);
  l_alter_stmt_2 varchar2(4000);
  l_adjust_stmt varchar2(4000);
  l_nextval number;
begin
  for r in (select * from user_sequences) loop
    l_adjust_stmt := 'select "' || r.sequence_name || '".nextval from dual';
    execute immediate l_adjust_stmt into l_nextval;
    l_alter_stmt_1 := 'ALTER SEQUENCE "' || r.sequence_name || '"'
        || ' INCREMENT BY '|| (r.min_value - l_nextval);
    l_alter_stmt_2 := 'ALTER SEQUENCE "' || r.sequence_name || '"'
        || ' INCREMENT BY ' || r.increment_by;
    dbms_output.put_line(l_alter_stmt_1);
--    execute immediate r.alter_stmt_1;
    dbms_output.put_line(l_adjust_stmt);
--    execute immediate l_adjust_stmt into l_nextval;
    dbms_output.put_line(l_alter_stmt_2);
--    execute immediate l_alter_stmt_2;
  end loop;
end;
/

PL/SQL procedure successfully completed.

ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY -101
select "SUPPLIER_SEQUENCE".nextval from dual
ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY 1

这个问题是关于11g的,但是。

您无法判断序列的原始值是什么。您只能基于
MINVALUE
,或者使用该值(即使为零),或者向其中添加一个值,或者仅在该值为非零时才这样做

您可以从
user\u sequences
视图中获取自己序列的当前值,并使用PL/SQL块循环它们,同时生成drop和create语句:

set serveroutput on
begin
  for r in (
    select 'DROP SEQUENCE "' || sequence_name || '"' as drop_stmt,
      'CREATE SEQUENCE "' || sequence_name || '"'
        || ' MINVALUE ' || min_value
        || ' MAXVALUE ' || max_value
        || ' INCREMENT BY ' || increment_by
        || ' START WITH ' || min_value
        || case when cache_size = 0 then ' NOCACHE' else ' CACHE ' || cache_size end
        || case when order_flag = 'Y' then ' ORDER' else ' NOORDER' end
        || case when cycle_flag = 'Y' then ' CYCLE' else ' NOCYCLE' end
        as create_stmt
    from user_sequences
  )
  loop
    dbms_output.put_line(r.drop_stmt);
--    execute immediate r.drop_stmt;
    dbms_output.put_line(r.create_stmt);
--    execute immediate r.create_stmt;
  end loop;
end;
/
我把
executeimmediate
语句注释掉了,以避免在没有任何检查的情况下复制和粘贴该语句时发生意外;最初,它只显示它将运行的命令,例如

PL/SQL procedure successfully completed.

DROP SEQUENCE "SUPPLIER_SEQUENCE"
CREATE SEQUENCE "SUPPLIER_SEQUENCE" MINVALUE 0 MAXVALUE 99999999999 INCREMENT BY 1 START WITH 0 CACHE 100 NOORDER NOCYCLE
...
如果您正在另一个架构中工作,并且具有正确的权限,则可以查询
all_sequences
dba_sequences
,并指定所有者:

    select 'DROP SEQUENCE "' || sequence_owner || '"."' || sequence_name ||'"' as drop_stmt,
      'CREATE SEQUENCE "' || sequence_owner || '"."' || sequence_name || '"'
        || ' MINVALUE ' || min_value
...
另一种方法是改变序列,将
增量设置为减去当前最高值(或最高值减去
MINVALUE
),调用
nextval
,然后重置增量。这在动态上有点混乱,主要是因为当直接在这样的循环中执行时,需要动态语句的第二级来获取当前序列值,但基本上是相同的想法:

declare
  l_nextval number;
begin
  for r in (
    select 'BEGIN EXECUTE IMMEDIATE ''ALTER SEQUENCE "' || sequence_name || '"'
        || ' INCREMENT BY -''|| ("' || sequence_name || '".nextval - ' || min_value ||'); END;'
        as alter_stmt_1,
      'SELECT "' || sequence_name || '".nextval from dual' as adjust_stmt,
      'ALTER SEQUENCE "' || sequence_name || '"'
        || ' INCREMENT BY ' || increment_by
        as alter_stmt_2
    from user_sequences
  )
  loop
    dbms_output.put_line(r.alter_stmt_1);
--    execute immediate r.alter_stmt_1;
    dbms_output.put_line(r.adjust_stmt);
--    execute immediate r.adjust_stmt into l_nextval;
    dbms_output.put_line(r.alter_stmt_2);
--    execute immediate r.alter_stmt_2;
  end loop;
end;
/

PL/SQL procedure successfully completed.

BEGIN EXECUTE IMMEDIATE 'ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY -'|| ("SUPPLIER_SEQUENCE".nextval - 0); END;
SELECT "SUPPLIER_SEQUENCE".nextval from dual
ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY 1
您还可以在循环中生成动态语句,这对于这种方法来说可能有点整洁:

declare
  l_alter_stmt_1 varchar2(4000);
  l_alter_stmt_2 varchar2(4000);
  l_adjust_stmt varchar2(4000);
  l_nextval number;
begin
  for r in (select * from user_sequences) loop
    l_adjust_stmt := 'select "' || r.sequence_name || '".nextval from dual';
    execute immediate l_adjust_stmt into l_nextval;
    l_alter_stmt_1 := 'ALTER SEQUENCE "' || r.sequence_name || '"'
        || ' INCREMENT BY '|| (r.min_value - l_nextval);
    l_alter_stmt_2 := 'ALTER SEQUENCE "' || r.sequence_name || '"'
        || ' INCREMENT BY ' || r.increment_by;
    dbms_output.put_line(l_alter_stmt_1);
--    execute immediate r.alter_stmt_1;
    dbms_output.put_line(l_adjust_stmt);
--    execute immediate l_adjust_stmt into l_nextval;
    dbms_output.put_line(l_alter_stmt_2);
--    execute immediate l_alter_stmt_2;
  end loop;
end;
/

PL/SQL procedure successfully completed.

ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY -101
select "SUPPLIER_SEQUENCE".nextval from dual
ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY 1

问题是关于11g的,但是。

是最初创建它时使用的MINVALUE,还是开始使用的MINVALUE?原始的起始值无论如何都不会存储,因此您是否假设要以MINVALUE+1开始?您不能从受控制的DDL脚本中删除并重新创建它们吗?您在源代码管理中有这些脚本,对吗?使用最初创建它们时使用的MINVALUE或开始使用的MINVALUE进行读取?原始的起始值无论如何都不会存储,因此您是否假设要以MINVALUE+1开始?您不能从受控制的DDL脚本中删除并重新创建它们吗?您在源代码管理中有这些脚本,对吗?请阅读