【问题标题】:Auto-increment column: differences in SQL syntax between Oracle and MySQL自增列:Oracle 和 MySQL 的 SQL 语法差异
【发布时间】:2011-12-28 07:24:34
【问题描述】:

我是一名大学生,需要使用 Oracle 的 iSQL* Plus 提交课程作业。

我正在尝试使用以下 SQL 语句创建一个表:

    CREATE  TABLE  Category 
( `id` INT(11) NOT NULL AUTO_INCREMENT ,
  `title` VARCHAR (45) NULL ,
  PRIMARY KEY (`id`) );

这会导致以下消息:

ORA-00911: 无效字符

它指的是勾号`符号。所以我尝试了以下方法,改用单引号:

    CREATE  TABLE  Category 
( 'id' INT(11) NOT NULL AUTO_INCREMENT ,
  'title' VARCHAR (45) NULL ,
  PRIMARY KEY ('id') );

错误:

ORA-00904: : 无效标识符

所以再试一次“ - 错误:

( "id" INT(11) NOT NULL AUTO_INCREMENT ,
          *

ORA-00907: 缺少右括号

如果我删除 INT 后面的 (11),它将抱怨 AUTO_INCREMENT 属性。

    CREATE  TABLE  Category 
( "id" INT NOT NULL AUTO_INCREMENT ,
  "title" VARCHAR (45) NULL ,
  PRIMARY KEY ("id") );

我认为 SQL 就是 SQL,在这些非常基本的级别上并没有真正的区别。我认为事情在更深层次上变得不同了?

  • 我如何让我的声明发挥作用?
  • 对于熟悉 MySQL 的人学习 Oracle,您有什么建议?

【问题讨论】:

  • Richard:您遇到了两种产品之间的差异以及它们在 SQL 语言标准上的不同扩展。是的,它们都支持 ANSI SQL,但是当您接近自动增量时,您会变得更深入。
  • 感谢 p.campbell 的评论。我想我应该开始阅读 Oracle 的 SQL 基础知识

标签: mysql oracle


【解决方案1】:

并非所有 SQL 都是相同的。 Oracle 和 MySQL 都不支持 IDENTITY 的实际 SQL 标准。

Oracle 不使用反引号...您实际上不需要引用您的标识符。最好不要这样做,这样您就不会在标识符中无意中使用无效字符。

Oracle 数字称为 NUMBER,可以采用可选的精度和小数位数。

CREATE TABLE Category
(
  id    NUMBER(11)   NOT NULL,
  title VARCHAR2(45) NULL,
  PRIMARY KEY (id)
)

要执行 AUTO_INCREMENT,请创建一个序列:

CREATE SEQUENCE seq_category_id START WITH 1 INCREMENT BY 1;

然后当你插入表格时,这样做:

INSERT INTO category
VALUES (seq_category_id.nextval, 'some title');

要自动执行此操作,如 AUTO_INCREMENT,请使用插入前触发器:

-- Automatically create the incremented ID for every row:
CREATE OR REPLACE trigger bi_category_id
BEFORE INSERT ON category
FOR EACH ROW
BEGIN
    SELECT seq_category_id.nextval INTO :new.id FROM dual;
END;

或者:

-- Allow the user to pass in an ID to be used instead
CREATE OR REPLACE TRIGGER bi_category_id
BEFORE INSERT ON category
FOR EACH ROW
DECLARE
    v_max_cur_id NUMBER;
    v_current_seq NUMBER;
BEGIN
    IF :new.id IS NULL THEN
        SELECT seq_category_id.nextval INTO :new.id FROM dual;
    ELSE
        SELECT greatest(nvl(max(id),0), :new.id) INTO v_max_cur_id FROM category;
        SELECT seq_category_id.nextval INTO v_current_seq FROM dual;
        WHILE v_current_seq < v_max_cur_id
        LOOP
            SELECT seq_category_id.nextval INTO v_current_seq FROM dual;
        END LOOP;
    END IF;
END;

现在,就发现这些差异而言,您通常只需搜索“oracle identity”或“oracle auto_increment”之类的内容即可了解 Oracle 是如何做到这一点的。

【讨论】:

  • 感谢 Scott A 的解释。
【解决方案2】:

Oracle 没有自动递增列。您需要创建一个sequencebefore insert 触发器,从序列中读取NEXTVAL 并设置列的值

【讨论】:

    猜你喜欢
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 2021-09-04
    • 2014-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多