表的命名规则:以字母为前缀,长度不能超过30个字符,表名中可以出现的合法的符号:大小写字母 数字 _ $ #
另外在同一个用户模式下,不能有两个表名相同的表,而且表名不能使用oracle的保留字
创建表需要有创建表的权限以及足够的表空间
create table oracle.dept1(deptno number(4),dname varchar2(10),loc varchar2(15));
在创建表的时候可以对列进行默认值的设定
create table emp1(empno number(4),ename varchar(10),hiredate date default sysdate);
insert into emp1(empno,ename) values(123,'mike');
select * from emp1;
EMPNO ENAME HIREDATE ---------- ---------- --------- 123 mike 01-MAY-18 Elapsed: 00:00:00.00
在没有向表中的hiredate插入值得时候,就以建表时候的默认值插入该列
表的约束条件,保证表中插入的数据符合要求
create table emp2(empno number(4) not null);
非空约束,保证这一列非空
insert into emp2 values(null);
insert into emp2 values(null) * ERROR at line 1: ORA-01400: cannot insert NULL into ("ORACLE"."EMP2"."EMPNO") Elapsed: 00:00:00.02
如果要查看表中的约束,可以查看user_constraints视图
desc user_constraints
--** select table_name,constraint_name,constraint_type from user_constraints;
TABLE_NAME CONSTRAINT_NAME C ------------------------------ ------------------------------ - EMP2 SYS_C0011094 C Elapsed: 00:00:00.29可以给约束起个名字
create table emp2(empno number(4) constraint nn_emp2_empno not null);
--** select table_name,constraint_name,constraint_type from user_constraints;
TABLE_NAME CONSTRAINT_NAME C ------------------------------ ------------------------------ - EMP2 NN_EMP2_EMPNO C Elapsed: 00:00:00.20
删除之前的表
drop table emp1 purge; drop table emp2 purge; drop table dept1 purge;
唯一约束
create table e1(empno number(4) constraints uk_e1_empno unique);
--** select table_name,constraint_name,constraint_type from user_constraints;
TABLE_NAME CONSTRAINT_NAME C ------------------------------ ------------------------------ - E1 UK_E1_EMPNO U Elapsed: 00:00:00.05
drop table e1 purge;
主键约束:不允许有空值,不允许有重复值
create table test(a number(4) constraint pk_test_a primary key);
TABLE_NAME CONSTRAINT_NAME C ------------------------------ ------------------------------ - TEST PK_TEST_A P Elapsed: 00:00:00.07
drop table test purge;
外键约束
建立主键表
create table tast(empno number(20) constraint pk_test_empno primary key);
建立外键表
create table test(empno number(4) constraint fk_test1_empno references tast,ename varchar2(10));
--** select table_name,constraint_name,constraint_type from user_constraints;
TABLE_NAME CONSTRAINT_NAME C ------------------------------ ------------------------------ - TEST FK_TEST1_EMPNO R TAST PK_TEST_EMPNO P Elapsed: 00:00:00.06
insert into test values(1,'next');
insert into test values(1,'next') * ERROR at line 1: ORA-02291: integrity constraint (ORACLE.FK_TEST1_EMPNO) violated - parent key not found Elapsed: 00:00:00.01
当设置外键约束后,受外键约束的列的值必须来源于与之关联的父表的主键
我们先在父表中插入相应的主键
insert into tast values(1);
insert into test values(1,'tom');
select * from test;
EMPNO ENAME ---------- ---------- 1 tom Elapsed: 00:00:00.00
insert into test values(null,'tom');
select * from test;
EMPNO ENAME ---------- ---------- 1 tom tom Elapsed: 00:00:00.00
我们发现,有外键约束的情况下,空值是可以被插入的
如果父表中的主键被外键参照,则父表的主键不能删除
delete from tast where empno=1;
delete from tast where empno=1 * ERROR at line 1: ORA-02292: integrity constraint (ORACLE.FK_TEST1_EMPNO) violated - child record found Elapsed: 00:00:00.01
我们重建一下外键约束
alter table test drop constraint fk_test1_empno;
alter table test add constraint fk_test1_empno foreign key(empno) references tast on delete set null;
然后我们再删除字表中的数据试试
delete from test where empno=1;
select * from test;
EMPNO ENAME ---------- ---------- tom Elapsed: 00:00:00.00
我们发现数据并没有被完全删除,只是外键字段被置为空
再重建外键约束
alter table test drop constraint fk_test1_empno;
alter table test add constraint fk_tast_empno foreign key(empno) references tast on delete cascade;
select * from tast;
EMPNO ---------- 1 Elapsed: 00:00:00.00
select * from test;
EMPNO ENAME ---------- ---------- 1 tom Elapsed: 00:00:00.01
delete from tast where empno=1;
select * from tast;
no rows selected Elapsed: 00:00:00.00
select * from test;
no rows selected Elapsed: 00:00:00.00
我们发现,由于删除了父表的主键值,字表的外键行数据也被删除了
check约束
alter table test add(sal number(7,2));
alter table test add constraint ck_test_sal check(sal>100);
insert into test values(1,'bob',10);
insert into test values(1,'bob',10) * ERROR at line 1: ORA-02290: check constraint (ORACLE.CK_TEST_SAL) violated Elapsed: 00:00:00.01
我们插入大于100的值
insert into test values(1,'bob',101);
select * from test;
EMPNO ENAME SAL ---------- ---------- ---------- 1 tom 1 bob 101 Elapsed: 00:00:00.00
如果在创建表之后添加约束,而表中已经有不符合约束的数据,约束是不会添加成功的,必须让表中所有字段满足约束后才能添加相应的约束
select * from test;
EMPNO ENAME SAL ---------- ---------- ---------- 1 tom 1 bob 101
alter table test add constraint ck_test_ename check (ename='tom');
alter table test add constraint ck_test_ename check (ename='tom') * ERROR at line 1: ORA-02293: cannot validate (ORACLE.CK_TEST_ENAME) - check constraint violated Elapsed: 00:00:00.01
delete from test where sal =101;
alter table test add constraint ck_test_ename check (ename='tom');
Table altered. Elapsed: 00:00:00.02
通过子查询创建表结构,除了非空约束,其他约束是不会复制过来的
create table tt as select * from emp where 1=2;
修改表结构
在表中添加列的定义,同时可以添加默认值
alter table test add (deptno number(7));
alter table test add(hiredate date default sysdate);
同时可以查看表中的默认值
--** select column_name,data_default from user_tab_columns where table_name='TEST';
COLUMN_NAME DATA_DEFAULT ------------------------------ ------------------ EMPNO ENAME SAL DEPTNO HIREDATE sysdate Elapsed: 00:00:00.02
修改表总列的定义
alter table test modify(deptno number(8));
删除表中的列
alter table test drop (hiredate);
生产环境中,可以先把列设置为不可用,之后进行删除
alter table test set unused column ename;
desc test
Name Null? Type ---------- -------- --------------------- EMPNO NUMBER(4) SAL NUMBER(7,2) DEPTNO NUMBER(8)
等到业务量少,确认无误的时候再进行删除
alter table test drop unused columns;
重命名表名
rename test to test1;
rename test1 to test;
将表设置为只读,设置为只读后,任何对表操作的DDL都不会成功(包括truncate),但是可以直接删除表(因为修改的是数据字典中的数据,并非修改表的内容)
alter table test read only;