是否有类似“的东西?”;如果不存在,则创建序列…”;在Oracle SQL中?

是否有类似“的东西?”;如果不存在,则创建序列…”;在Oracle SQL中?,sql,oracle,sequence,Sql,Oracle,Sequence,对于使用Oracle8DB的应用程序,我提供了一个SQL脚本来设置触发器、序列等内容,这些内容可以复制并粘贴到SQL*Plus中。如果我试图创建的序列已经存在,我希望脚本不会因为错误而停止。对于触发器,可以使用“创建或替换触发器…”轻松完成此操作,但对于序列,此操作不起作用。我还尝试了“如果mysequence不存在,那么创建sequence…”但它也不存在。有其他选择吗 或者,如果这是不可能的,是否有一种方法可以在不使用SQL*的情况下执行“drop sequence mysequence”,

对于使用Oracle8DB的应用程序,我提供了一个SQL脚本来设置触发器、序列等内容,这些内容可以复制并粘贴到SQL*Plus中。如果我试图创建的序列已经存在,我希望脚本不会因为错误而停止。对于触发器,可以使用“创建或替换触发器…”轻松完成此操作,但对于序列,此操作不起作用。我还尝试了“如果mysequence不存在,那么创建sequence…”但它也不存在。有其他选择吗


或者,如果这是不可能的,是否有一种方法可以在不使用SQL*的情况下执行“drop sequence mysequence”,并在mysequence不存在时中止脚本?

您可以检查
user\u sequence
表以查看正在创建的序列是否已经存在

与davek的解决方案类似: 其思想是,在创建任何序列之前,删除序列并创建它,所有这些都在动态SQL中,创建一个函数,并说当需要创建10个序列时,让函数来处理

function crt_seq(p_seq_name varchar2)
return boolean
begin
   for i in (select 1 from user_sequence where sequence_name = upper(p_seq_name))
   loop
   ---- Already exists. You can drop and recreate or return false to error out
   execute immediate 'drop sequence '||p_seq_name;
   execute immediate 'create sequence '||p_seq_name||' start with 1 increment
                    by 1 nocache';
   end loop;
   return true;
exception
when others then
   return false;
end;

您可以参数化所有其他选项,并具有一个详细的函数来为您创建序列。

如果您确定脚本将始终在SQL*Plus下运行,您可以在create sequence语句中插入一个指令,以便在出现错误时继续:

WHENEVER SQLERROR CONTINUE
-- create sequences here, ignoring errors
WHENEVER SQLERROR EXIT SQL.SQLCODE
请注意,如果在create sequence语句中存在其他错误(权限问题、语法错误等),它们将被忽略

我喜欢:

DECLARE
  v_dummy NUMBER;
BEGIN
  -- try to find sequence in data dictionary
  SELECT 1
  INTO v_dummy
  FROM user_sequences
  WHERE sequence_name = 'MY_SEQUENCE_NAME';

  -- if sequence found, do nothing
EXCEPTION
  WHEN no_data_found THEN
    -- sequence not found, create it
    EXECUTE IMMEDIATE 'create sequence my_sequence_name';
END;
DECLARE
  C NUMBER;
BEGIN
  SELECT COUNT(*) INTO C
  FROM ALL_TRIGGERS
  WHERE OWNER = 'YOUROWNER'
  AND TRIGGER_NAME = 'YOURTRIGGER';

  IF (C = 0) THEN
    EXECUTE IMMEDIATE '
      CREATE TRIGGER "YOUROWNER"."YOURTRIGGER"
        blah blah blah your trigger blah blah
    ';
  END IF;
END;
/


Oracle中的AUTOINCREMENT函数将如何帮助解决明显的源代码管理/配置管理问题?@APC:对不起,我不明白。您能更详细地解释一下吗?我的意思是:表只需要一个AUTOINCREMENT字段。例如,在SQL Server中,我只是将列定义为autoinc字段,而我需要一个我完成了。在Oracle中,我需要创建一个数字列,然后创建一个序列,然后创建一个触发器来使用该序列填充我的列。这对我来说似乎不是很严格。我的观点是,如果您有适当的模式管理,您就不需要处理序列的先前存在,因为您将只运行一个create sequence语句t针对您知道序列不存在的数据库。嗯,我需要为具有不同版本数据库的不同客户以及新客户使用该脚本。我当然可以确定哪个客户有什么模式,并有选择地为他们创建更新脚本,并且也有一个单独的脚本用于初始设置,但用于sim卡plicity我更喜欢有一个脚本,我可以为每个人都使用。这使我的支持部门同事和安装技术人员在不了解Oracle的情况下更轻松,对我来说,因为有人使用了错误的脚本,所以我不需要整理帮助电话:-)很好,我不知道这一点谢谢!我必须承认我是Oracle的新手,我甚至不知道在哪里定义该函数以及如何从我的SQL脚本调用它,但我的桌面上已经有关于Oracle的书籍,所以当我有更多的知识时,你的回答可能会帮到我:-)谢谢。警告:如果你有代码(例如软件包)使用序列将使它们无效。如果在运行此代码时这些包正在使用,则可能还会出现锁定问题。哦,如果序列已经存在并已被使用,则会得到重复的值。我将表名更改为“user_sequences”,以便在我的桌子
DECLARE
  lsSeqName VARCHAR2(32 CHAR) := UPPER('MY_SEQUENCE_NAME');
  lnSeqCount NUMBER;
BEGIN
  -- try to find sequence in data dictionary
  SELECT count(1)
    INTO lnSeqCount
    FROM user_sequences
    WHERE UPPER(sequence_name) = lsSeqName;
  -- if sequence not found, create it
  IF lnSeqCount = 0 THEN
    EXECUTE IMMEDIATE 'CREATE SEQUENCE ' || lsSeqName || ' START WITH 1 MINVALUE 1 MAXVALUE 1000000000000000 INCREMENT BY 1 NOCYCLE CACHE 20 NOORDER';
  END IF;
END;
/
-- helper method
PROCEDURE createSeqIfNotExists (
  isSeqName VARCHAR2
) IS
  lnSeqCount NUMBER;
BEGIN
  -- try to find sequence in data dictionary
  SELECT count(1)
    INTO lnSeqCount
    FROM user_sequences
    WHERE UPPER(sequence_name) = UPPER(isSeqName);
  -- if sequence not found, create it
  IF lnSeqCount = 0 THEN
    EXECUTE IMMEDIATE 'CREATE SEQUENCE ' || UPPER(isSeqName) || ' START WITH 1 MINVALUE 1 MAXVALUE 1000000000000000 INCREMENT BY 1 NOCYCLE CACHE 20 NOORDER';
  END IF;
END createSeqIfNotExists;

-- call method
BEGIN
  createSeqIfNotExists('MY_SEQUENCE_NAME');
END;
/