orcale主键自增写法

1.如果这张表建了序列sequence,并且这个序列想让ID自增:

查询序列方法:
select * from user_sequences where sequence_name like '%seq_user%'

那么我的insert语句应该这么写:
insert into user(ID,userName) values (seq_user.nextval,“小王”);

2.如果没有建立序列,那么需要对这个user表建立一个序列:

create sequence seq_user
increment by 1
start with 1
minvalue 1
maxvalue 9999999
order
cache 20
cycle;

这是序列的含义:

和mysql中使用auto_increment不同,oracle中使用序列来实现主键自增,使用序列前必须要先创建一个序列
create sequence seq_users 序列名称
increment by 1 每次增长多少
start with 1 从几开始
minvalue 1 最小值
maxvalue 999999999 最大值
cycle/no cycle 序列到达最大值之后怎么办,一般去cycle
cache 20 需要不需要使用缓存,就是一次生成多少个序列的值,如果生成了多个序列值,如果缓存中有数据, 就
不需要查询缓存了
order/noorder 获取序列的时候是否按顺序给值。如果多用户一起获取序列的值,使用order可以保证序列值的顺
序按访问序列的事件排序。

创建好了以后,再插入数据:

insert into user(ID,userName) values (seq_user.nextval,“小王”);
————————————————
版权声明:本文为优快云博主「佐手烈焰魂」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qq_38286347/article/details/107707739

<think>我们比较Oracle和MySQL的SQL写法差异,并举例说明。 主要差异点包括: 1. 数据类型差异 2. 函数差异(如字符串、日期函数) 3. 分页查询 4. 连接语法(Oracle早期使用(+)表示外连接,而MySQL使用JOIN关键字) 5. 对SQL标准的支持程度(如窗口函数、CTE等,但现代版本两者都支持) 6. 其他语法细节(如Oracle的DUAL表,MySQL的LIMIT等) 下面通过具体例子说明: 1. 分页查询 - MySQL使用LIMIT进行分页 - Oracle使用ROWNUM或ROW_NUMBER()(在12c之前常用ROWNUM,12c之后有OFFSET-FETCH) 例子:查询第11到20行的数据 MySQL: ```sql SELECT * FROM table_name LIMIT 10 OFFSET 10; -- 或者 SELECT * FROM table_name LIMIT 10, 10; ``` Oracle (12c之前): ```sql SELECT * FROM ( SELECT t.*, ROWNUM rn FROM ( SELECT * FROM table_name ORDER BY some_column ) t WHERE ROWNUM <= 20 ) WHERE rn > 10; ``` Oracle (12c及之后): ```sql SELECT * FROM table_name OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY; ``` 2. 字符串连接 - MySQL使用CONCAT函数(可以多个参数) - Oracle使用`||`操作符,或者CONCAT函数(但CONCAT只能两个参数) 例子:将姓和名连接 MySQL: ```sql SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees; ``` Oracle: ```sql SELECT first_name || ' ' || last_name AS full_name FROM employees; -- 或者 SELECT CONCAT(CONCAT(first_name, ' '), last_name) AS full_name FROM employees; -- 比较麻烦 ``` 3. 日期处理 - MySQL使用NOW()获取当前日期时间 - Oracle使用SYSDATE 例子:获取当前日期 MySQL: ```sql SELECT NOW(); ``` Oracle: ```sql SELECT SYSDATE FROM DUAL; ``` 4. 伪表 - Oracle的SELECT语句必须包含FROM子句,因此当没有表时使用DUAL - MySQL可以没有FROM子句 例子:计算1+1 MySQL: ```sql SELECT 1+1; ``` Oracle: ```sql SELECT 1+1 FROM DUAL; ``` 5. 外连接 - MySQL使用LEFT JOIN, RIGHT JOIN等 - Oracle除了标准JOIN外,还支持旧的(+)操作符(在左连接的右侧表条件后加(+)表示该表为从表) 例子:左连接 MySQL: ```sql SELECT a.*, b.* FROM table_a a LEFT JOIN table_b b ON a.id = b.a_id; ``` Oracle (传统写法): ```sql SELECT a.*, b.* FROM table_a a, table_b b WHERE a.id = b.a_id(+); ``` 6. 插入数据(自主键) - MySQL通常使用AUTO_INCREMENT - Oracle使用序列(SEQUENCE)和触发器(或手动插入序列值) 例子:插入数据,主键 MySQL: ```sql CREATE TABLE example ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) ); INSERT INTO example (name) VALUES ('test'); ``` Oracle: ```sql CREATE SEQUENCE example_seq; CREATE TABLE example ( id NUMBER PRIMARY KEY, name VARCHAR2(50) ); -- 方式1:手动使用序列 INSERT INTO example (id, name) VALUES (example_seq.NEXTVAL, 'test'); -- 方式2:创建触发器自动设置 ``` 7. 空值判断 - MySQL和Oracle都支持IFNULL/NVL,但函数名不同 - MySQL: IFNULL(expr1, expr2) - Oracle: NVL(expr1, expr2) 例子:将空值替换为0 MySQL: ```sql SELECT IFNULL(salary, 0) FROM employees; ``` Oracle: ```sql SELECT NVL(salary, 0) FROM employees; ``` 8. 正则表达式 - 两者都支持正则表达式,但函数名和用法略有不同 - MySQL: REGEXP_LIKE, REGEXP_REPLACE等(MySQL8.0开始支持) - Oracle: REGEXP_LIKE, REGEXP_REPLACE等(Oracle10g开始支持) 9. 窗口函数(分析函数) - 两者都支持窗口函数,语法基本一致,但函数名可能略有不同(如Oracle有LISTAGG,MySQL8.0有JSON_ARRAYAGG等) 10. 存储过程和函数 - 两者在存储过程和函数的语法上有较大差异(如变量声明、循环语法等) 由于篇幅限制,这里不展开所有细节。在实际开发中,应尽量使用标准SQL,减少数据库迁移的难度。 总结:Oracle和MySQL在SQL语法上存在一定差异,但都遵循SQL标准。在编写跨数据库的SQL时,可以使用ORM工具或数据库抽象层来屏蔽差异,或者根据数据库类型动态生成SQL。 注意:以上例子基于较新版本的MySQL(5.7+)和Oracle(11g+),具体版本支持情况请参考官方文档。 §§相关问题§§: 1. Oracle和MySQL在事务隔离级别上有什么不同? 2. 如何将Oracle数据库迁移到MySQL,需要注意哪些问题? 3. 在MySQL中如何实现类似Oracle的序列(SEQUENCE)功能? 4. 请举例说明Oracle和MySQL在日期函数上的其他差异。</think>### Oracle 与 MySQL 的 SQL 写法差异详解 以下是主要差异及代码示例: --- #### 1. **分页查询** - **MySQL**:`LIMIT` + `OFFSET` ```sql SELECT * FROM employees ORDER BY hire_date LIMIT 10 OFFSET 20; -- 跳过20行,取10行 ``` - **Oracle**:`ROWNUM` 或 `FETCH FIRST`(12c+) ```sql -- 传统写法 (Oracle 11g) SELECT * FROM ( SELECT t.*, ROWNUM rn FROM ( SELECT * FROM employees ORDER BY hire_date ) t WHERE ROWNUM <= 30 -- 结束行 ) WHERE rn > 20; -- 起始行 -- 现代写法 (Oracle 12c+) SELECT * FROM employees ORDER BY hire_date OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY; ``` --- #### 2. **字符串连接** - **MySQL**:`CONCAT()` ```sql SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees; ``` - **Oracle**:`||` 或 `CONCAT()`(仅支持两参数) ```sql SELECT first_name || ' ' || last_name AS full_name FROM employees; -- CONCAT() 需嵌套处理多参数 SELECT CONCAT(CONCAT(first_name, ' '), last_name) AS full_name FROM employees; ``` --- #### 3. **日期处理** - **MySQL**:`NOW()` + `DATE_FORMAT()` ```sql SELECT NOW(), DATE_FORMAT(hire_date, '%Y-%m-%d') AS formatted_date FROM employees; ``` - **Oracle**:`SYSDATE` + `TO_CHAR()` ```sql SELECT SYSDATE, TO_CHAR(hire_date, 'YYYY-MM-DD') AS formatted_date FROM employees; ``` --- #### 4. **空值处理** - **MySQL**:`IFNULL()` ```sql SELECT name, IFNULL(salary, 0) AS salary FROM employees; ``` - **Oracle**:`NVL()` ```sql SELECT name, NVL(salary, 0) AS salary FROM employees; ``` --- #### 5. **伪表与计算** - **MySQL**:无需 `FROM` ```sql SELECT 1 + 1; -- 直接计算 ``` - **Oracle**:必须用 `FROM DUAL` ```sql SELECT 1 + 1 FROM DUAL; -- DUAL是虚拟表 ``` --- #### 6. **外连接语法** - **MySQL**:`LEFT JOIN` ```sql SELECT e.name, d.department_name FROM employees e LEFT JOIN departments d ON e.dept_id = d.id; ``` - **Oracle**:`(+)`(旧式写法) ```sql SELECT e.name, d.department_name FROM employees e, departments d WHERE e.dept_id = d.id(+); -- (+) 表示右表可能为空 ``` --- #### 7. **自主键** - **MySQL**:`AUTO_INCREMENT` ```sql CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) ); ``` - **Oracle**:序列 + 触发器 ```sql CREATE SEQUENCE users_seq; CREATE TABLE users ( id NUMBER PRIMARY KEY, name VARCHAR2(50) ); CREATE TRIGGER users_trigger BEFORE INSERT ON users FOR EACH ROW BEGIN SELECT users_seq.NEXTVAL INTO :new.id FROM DUAL; END; / ``` --- ### 关键差异总结 | 特性 | MySQL | Oracle | |--------------|-----------------------|----------------------| | **分页** | `LIMIT/OFFSET` | `ROWNUM`/`FETCH FIRST` | | **字符串连接**| `CONCAT()` | `||` | | **当前时间** | `NOW()` | `SYSDATE` | | **空值处理** | `IFNULL()` | `NVL()` | | **伪表** | 无需 `FROM` | `FROM DUAL` | | **外连接** | `LEFT JOIN` | `(+)` | | **自ID** | `AUTO_INCREMENT` | 序列 + 触发器 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值