Oracle/PostgreSQL中的序列,insert语句中没有ID
我正在尝试使用Smart sequence generator创建表,以使用此插入结构:Oracle/PostgreSQL中的序列,insert语句中没有ID,sql,oracle,postgresql,sequence,ddl,Sql,Oracle,Postgresql,Sequence,Ddl,我正在尝试使用Smart sequence generator创建表,以使用此插入结构: insert into SOMEUSERS (SOMEUSERS_NAME, SOMEUSERS_PASSWORD) values ('Artem', 'PracTimPatie'); 与此相反: insert into SOMEUSERS (SOMEUSERS_ID, SOMEUSERS_NAME, SOMEUSERS_PASSWORD) values (2, 'Artem', 'PracTimPa
insert into SOMEUSERS (SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values ('Artem', 'PracTimPatie');
与此相反:
insert into SOMEUSERS (SOMEUSERS_ID, SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values (2, 'Artem', 'PracTimPatie');
或该结构:
insert into SOMEUSERS (SOMEUSERS_ID, SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values (GEN_ID_SOMEUSERS.nextval, 'Artem', 'PracTimPatie');
执行以下sql脚本时:
create sequence gen_id_someUsers START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
CREATE TABLE loc_db.someUsers
( someUsers_id number(10) DEFAULT gen_id_someUsers.NEXTVAL NOT NULL, --because of this row
someUsers_name varchar2(50) NOT NULL,
someUsers_password varchar2(50),
CONSTRAINT someUsers_pk PRIMARY KEY (someUsers_id)
);
我收到以下通知:
错误报告-SQL错误:ORA-00984:此处不允许列
98400000-“此处不允许使用列”
为清楚起见,他说在这种情况下:
...
CREATE TABLE loc_db.someUsers
( someUsers_id number(10) NOT NULL, --correct this row
...
序列GEN\u ID\u一些用户已创建
表LOC_DB.SOMEUSERS已创建
如何配置序列生成器?
(对于PostgreSQL也是这样的情况。如果可能,不使用触发器(尽可能容易)在postgres中,只需使用如下序列:
CREATE TABLE SOMEUSERS (
SOMEUSERS_ID serial NOT NULL,
SOMEUSERS_NAME text,
SOMEUSERS_PASSWORD text
);
您的insert语句很简单,如下所示:
INSERT INTO SOMEUSERS (SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values ('Artem', 'PracTimPatie');
如果你想查询序列,你可以像查询任何其他关系一样进行查询。在postgres中,只需使用如下序列:
CREATE TABLE SOMEUSERS (
SOMEUSERS_ID serial NOT NULL,
SOMEUSERS_NAME text,
SOMEUSERS_PASSWORD text
);
您的insert语句很简单,如下所示:
INSERT INTO SOMEUSERS (SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values ('Artem', 'PracTimPatie');
如果要查询序列,可以像查询任何其他关系一样进行查询。Oracle 12c介绍:
如果要在早期版本中执行此操作,则需要触发器和序列:
CREATE TABLE SOMEUSERS (
SOMEUSERS_ID NUMBER(10)
CONSTRAINT SOMEUSERS__SOMEUSERS_ID__PK PRIMARY KEY,
SOMEUSERS_NAME VARCHAR2(50)
CONSTRAINT SOMEUSERS__SOMEUSERS_NAME__NN NOT NULL,
SOMEUSERS_PASSWORD VARCHAR2(50)
);
/
CREATE SEQUENCE gen_id_someUsers START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
/
CREATE OR REPLACE TRIGGER SOMEUSERS__ID__TRG
BEFORE INSERT ON SOMEUSERS
FOR EACH ROW
BEGIN
:new.SOMEUSERS_ID := gen_id_someUsers.NEXTVAL;
END;
/
INSERT INTO SOMEUSERS (
SOMEUSERS_NAME,
SOMEUSERS_PASSWORD
) VALUES (
'Name',
'Password'
);
然后,您只需执行以下操作(使用标识列或触发器与序列组合):
Oracle 12c推出:
如果要在早期版本中执行此操作,则需要触发器和序列:
CREATE TABLE SOMEUSERS (
SOMEUSERS_ID NUMBER(10)
CONSTRAINT SOMEUSERS__SOMEUSERS_ID__PK PRIMARY KEY,
SOMEUSERS_NAME VARCHAR2(50)
CONSTRAINT SOMEUSERS__SOMEUSERS_NAME__NN NOT NULL,
SOMEUSERS_PASSWORD VARCHAR2(50)
);
/
CREATE SEQUENCE gen_id_someUsers START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
/
CREATE OR REPLACE TRIGGER SOMEUSERS__ID__TRG
BEFORE INSERT ON SOMEUSERS
FOR EACH ROW
BEGIN
:new.SOMEUSERS_ID := gen_id_someUsers.NEXTVAL;
END;
/
INSERT INTO SOMEUSERS (
SOMEUSERS_NAME,
SOMEUSERS_PASSWORD
) VALUES (
'Name',
'Password'
);
然后,您只需执行以下操作(使用标识列或触发器与序列组合):
其他答案涉及postgreSQL和Oracle 12c,因此我将在这里介绍Oracle 11.2或更早版本 从11.1 SQL参考手册: 违约 如果后续INSERT语句省略了该列的值,则可以使用DEFAULT子句指定要分配给该列的值。表达式的数据类型必须与该列的数据类型匹配。该列的长度也必须足以容纳该表达式 默认表达式可以包含任何SQL函数,只要该函数不返回文字参数、列引用或嵌套函数调用 对默认列值的限制 默认表达式不能包含对PL/SQL函数或其他列、伪列CURRVAL、NEXTVAL、LEVEL、previor和ROWNUM的引用,或未完全指定的日期常量的引用 (强调矿山) 因此,由于不能将
sequence.NEXTVAL
作为默认值,因此基本上必须使用触发器:
CREATE OR REPLACE TRIGGER SOMEUSERS_BI
BEFORE INSERT
ON LOC_DB.SOMEUSERS
FOR EACH ROW
BEGIN
IF :NEW.SOMEUSERS_ID THEN
:NEW.SOMEUSERS_ID := GEN_ID_SOMEUSERS.NEXTVAL;
END IF;
END SOMEUSERS_BI;
根据我的经验,除了在Oracle 11.2或更早版本中使用这样的触发器之外,没有可靠的替代方法
祝你好运。其他答案都提到了postgreSQL和Oracle 12c,因此我将在这里提到Oracle 11.2或更早版本 从11.1 SQL参考手册: 违约 如果后续INSERT语句省略了该列的值,则可以使用DEFAULT子句指定要分配给该列的值。表达式的数据类型必须与该列的数据类型匹配。该列的长度也必须足以容纳该表达式 默认表达式可以包含任何SQL函数,只要该函数不返回文字参数、列引用或嵌套函数调用 对默认列值的限制 默认表达式不能包含对PL/SQL函数或其他列、伪列CURRVAL、NEXTVAL、LEVEL、previor和ROWNUM的引用,或未完全指定的日期常量的引用 (强调矿山) 因此,由于不能将
sequence.NEXTVAL
作为默认值,因此基本上必须使用触发器:
CREATE OR REPLACE TRIGGER SOMEUSERS_BI
BEFORE INSERT
ON LOC_DB.SOMEUSERS
FOR EACH ROW
BEGIN
IF :NEW.SOMEUSERS_ID THEN
:NEW.SOMEUSERS_ID := GEN_ID_SOMEUSERS.NEXTVAL;
END IF;
END SOMEUSERS_BI;
根据我的经验,除了在Oracle 11.2或更早版本中使用这样的触发器之外,没有可靠的替代方法
祝你好运。在Postgres中,只需将列定义为
serial
:在Oracle中,在11g之前不能使用序列作为默认值。在该版本中,你必须使用触发器。在Oracle 12g中,你实际上可以使用与你尝试使用的语法非常类似的语法。在Postgres中,只需将列定义为serial
:你不能使用Oracle 11g之前的默认序列。您必须在该版本中使用触发器。在Oracle 12g中,您实际上可以使用与您尝试使用的语法非常类似的语法。