我尝试用聪明的序列生成器创建表来使用这个insert-strucure:
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:此处不允许使用列 00984. 00000 - "栏目不允许在这里"
为清楚起见,在这种情况下说:
...
CREATE TABLE loc_db.someUsers
( someUsers_id number(10) NOT NULL, --correct this row
...
创建序列GEN_ID_SOMEUSERS。
表LOC_DB.SOMEUSERS已创建。
(如果 PostgreSQL也是。如果可能,没有触发器(尽可能容易)
答案 0 :(得分:2)
在postgres中只需使用如下序列:
CREATE TABLE SOMEUSERS (
SOMEUSERS_ID serial NOT NULL,
SOMEUSERS_NAME text,
SOMEUSERS_PASSWORD text
);
您的插入语句很简单:
INSERT INTO SOMEUSERS (SOMEUSERS_NAME, SOMEUSERS_PASSWORD)
values ('Artem', 'PracTimPatie');
如果你想查询序列,你可以像任何其他关系一样查询它。
答案 1 :(得分:2)
Oracle 12c引入了Identity columns:
CREATE TABLE SOMEUSERS (
SOMEUSERS_ID NUMBER(10) GENERATED ALWAYS AS IDENTITY
CONSTRAINT SOMEUSERS__SOMEUSERS_ID__PK PRIMARY KEY,
SOMEUSERS_NAME VARCHAR2(50)
CONSTRAINT SOMEUSERS__SOMEUSERS_NAME__NN NOT NULL,
SOMEUSERS_PASSWORD VARCHAR2(50)
);
如果您想在早期版本中执行此操作,则需要触发器和序列:
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'
);
答案 2 :(得分:2)
其他答案已经解决了postgreSQL和Oracle 12c,所以我将在这里解决Oracle 11.2或更早版本。
从11.1 SQL参考手册:
DEFAULT
如果后续INSERT语句省略了列的值,则DEFAULT子句允许您指定要分配给列的值。表达式的数据类型必须与列的数据类型匹配。该列也必须足够长以保存此表达式。
DEFAULT表达式可以包含任何SQL函数,只要该函数不返回文字参数,列引用或嵌套函数调用。
对默认列值的限制
DEFAULT表达式不能包含对 PL / SQL函数或其他列的引用,伪列CURRVAL, NEXTVAL ,LEVEL,PRIOR和ROWNUM,或者日期常量没有完全说明。
(强调我的)
因此,由于您无法将sequence.NEXTVAL
作为DEFAULT值,因此您基本上必须使用触发器:
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或更早版本中使用诸如此类的触发器没有可靠的替代方案。
祝你好运。