SQL(SQL/Oracle)使用序列从选择语句中插入值

Posted

技术标签:

【中文标题】SQL(SQL/Oracle)使用序列从选择语句中插入值【英文标题】:SQL(SQL/Oracle) insert value from a select statement using sequence 【发布时间】:2020-10-25 23:18:15 【问题描述】:

我想从如下所示的 select 语句中插入 (user_id) 值,而无需标识列。当前,此查询不按顺序遵循序列号。请多多指教。

https://dbfiddle.uk/?rdbms=oracle_18&fiddle=195728e48cc8a5a0047fec8837e9f217

【问题讨论】:

【参考方案1】:

这是回答问题的original version。

如果你问是否有相同的 SQL 语句在 SQL Server 和 Oracle 中使用序列,那么,不,你不能。

在 Oracle 中,语法是:

INSERT INTO b_user ( user_id /*, ... */ )
  VALUES ( b_user__user_id__seq.NEXT_VAL /*, ... */ );

在 SQL Server 中,语法为:

INSERT INTO b_user ( user_id /*, ... */ )
  VALUES ( NEXT VALUE FOR b_user__user_id__seq /*, ... */ );

在 Oracle 中,您可以将对序列的调用包装在一个函数中:

CREATE FUNCTION get_next_b_user_id RETURN INT
IS
BEGIN
  RETURN b_user__user_id__seq.NEXTVAL;
END;
/

那么你可以使用:

INSERT INTO b_user ( user_id /*, ... */ )
  VALUES ( get_next_b_user__id__seq() /*, ... */ );

但是,在 SQL server you cannot use a sequence in user-defined functions 中,Oracle 中的方法无法复制。


因此,简而言之,如果您使用的是序列,您将不得不为不同的数据库使用不同的 SQL 语句。

如果您想使用 IDENTITY 列,那么您可以在两者中获得相同的语法。

在甲骨文中:

CREATE TABLE b_user (
  user_id      INT
               GENERATED ALWAYS AS IDENTITY,
  user_name    VARCHAR(250),
  user_email   VARCHAR(250),
  user_address VARCHAR(250),
  user_city    VARCHAR(50),
  user_state   VARCHAR(5),
  user_country VARCHAR(5),
  user_zip     VARCHAR(10)
);

在 SQL Server 中:

CREATE TABLE b_user (
  user_id      INT IDENTITY(1,1),
  user_name    VARCHAR(250),
  user_email   VARCHAR(250),
  user_address VARCHAR(250),
  user_city    VARCHAR(50),
  user_state   VARCHAR(5),
  user_country VARCHAR(5),
  user_zip     VARCHAR(10)
)

然后,在这两个数据库中,您都可以使用以下语句:

insert into b_user (
  user_name,
  user_email,
  user_address,
  user_city,
  user_state,
  user_country,
  user_zip
) values (
  'Alice',
  'alice@example.com',
  'A house',
  'A city',
  'STATE',
  'ABC',
  'ZZ0123'
);

Oracle db<>fiddle 和 SQL Server db<>fiddle

【讨论】:

【参考方案2】:

一个选项是,如果您知道列 user_id 已经插入了一些值,那么当您创建一个将用于该列的序列时

--example you start with 3 if you know 2 is the maximum value for that column.
CREATE SEQUENCE b_user__user_id__seq  start with 3 ;

最好在该列中有一个主键或唯一约束。

【讨论】:

我有一个名为 user_id_pk 的 pk 列,它是主键。但我有一个名为 user_id 的非主键,它不是主键。不幸的是,user_id 和 user_id_pk 应该具有相同的值。我该怎么做。 @JSBeginner 使用sequence_name.NEXTVALsequence_name.CURRVAL

以上是关于SQL(SQL/Oracle)使用序列从选择语句中插入值的主要内容,如果未能解决你的问题,请参考以下文章

SQL - oracle - 如何从连接结果中选择特定部门

(SQL ORACLE)如何生成 html 输出,给定 select 语句?

我想编写一个 sql (Oracle SQL) 查询来从特定字符之后的列中选择字符串的一部分

sql Oracle PL / SQL填充排序顺序列中的空白

javaweb连接sql、oracle的详细过程和用法

SQL语句如何实现从数据库表中查询随机数据的记录