1. 程式人生 > 其它 >4.SQL(資料庫變更)

4.SQL(資料庫變更)

1.Insert(增加)

語法:
INSERT INTO表名[(列名1,列名2,...)]VALUES(值1,值2,...)
標準寫法

簡單寫法(不建議)
INSERT INTO 表名VALUES(值1,值2,...)
insert into myemp values(7789, '張三', '開發', 7839, to_date('1992-10-22', 'yyyy-MM-dd'), 2000, 200, 10);

注意:使用簡單的寫法必須按照表中的欄位的順序來插入值,而且如果有為空的欄位使用null

insert into myemp values(7790, '張三', '開發', null, to_date('1992-10-22', 'yyyy-MM-dd'), 2000, null, 10);

2.update(修改)

全部修改:UPDATE 表名 SET 列名1=值1,列名2=值2,....
區域性修改:UPDATE 表名 SET 列名1=值1,列名2=值2,....WHERE 修改條件;

全部更新

區域性更新

把張三的領導取消

3.delete(刪除)

語法 : DELETE FROM 表名 WHERE 刪除條件;

在刪除語句中如果不指定刪除條件的話就會刪除所有的資料

4.事務處理

範例:刪除員工7934;

從結果上看似乎資料已經刪除,但是我們再開啟另一個視窗檢視發現7934的員工還在

事務處理:所謂的事務管理就是要保證資料的完整性,要麼同時成功,要麼同時失敗
當我們執行完delete語句時,我們去資料庫中去檢視資料,發現並沒有我們刪除資料,這是因為oracle的事務對資料庫的變更的處理,我們必須做提交事務才能讓資料真正的插入到資料庫中,在同樣在執行完資料庫變更的操作後還可以把事務進行回滾,這樣就不會插入到資料庫。如果事務提交後則不可以再回滾。
提交:commit
回滾:rollback

在oracle中會資料庫變更會發生鎖的情況(此處應用可以解決專案多執行緒併發帶來的資料安全問題)
當兩個資料庫的連線同時來修改同一資料時,一定會有一連線先修改,另一個連線就會等待直到第一個連線修改完畢再修改

5.表的管理

1.常用的資料型別

No 資料型別 描述
1 Varchar, varchar2 表示一個字串
2 NUMBER NUMBER(n)表示一個整數,長度是n
NUMBER(m,n):表示一個小數,總長度是m,小數是n,整數是m-n
3 DATA 表示日期型別
4 CLOB 大物件,表示大文字資料型別,可存4G
5 BLOB 大物件,表示二進位制資料,可存4G

2.建表

語法:

Create table 表名(
欄位1 資料型別 [default 預設值],
欄位2 資料型別 [default 預設值],
...
欄位n 資料型別 [default 預設值]
);
範例:建立person表

create table person(
       pid      number(10),
       name     varchar2(10),
       gender   number(1)  default 1,
       birthday date
);

insert into person(pid, name, gender, birthday)
values(1, '張三', 1, to_date('1999-12-22', 'yyyy-MM-dd'));

3.表的刪除

語法:DROP TABLE 表名

4.表的修改

在sql中使用alter可以修改表

新增語法:ALTER TABLE 表名稱 ADD(列名1 型別 [DEFAULT 預設值],列名1 型別 [DEFAULT 預設值]...)
修改語法:ALTER TABLE 表名稱 MODIFY(列名1 型別 [DEFAULT 預設值],列名1 型別 [DEFAULT 預設值]...)

注意修改時如果原有某列的資料長度為200,則不可以把該列修改成小於200的列

範例:在person表中增加列address

alter table person add(address varchar2(10));

範例:把person表的address列的長度修改成20長度

alter table person modify(address varchar2(20));

5.截斷表

在person表中使用delete語句刪除資料,則可以使用rollback來回滾,如果想要清空一張表的資料,同時不想回滾可以立即釋放資源需要使用截斷表的語法
語法:TRUNCATE TABLE 表名
範例:截斷person表

truncate table person;

6.約束

在資料庫開發中,約束是必不可少,使用約束可以更好的保證資料的完整性。

1.主鍵約束

主鍵約束都是在id上使用,而且本身已經默認了內容不能為空,可以在建表的時候指定。

建立一張表,把pid作為主鍵

create table person(
       pid      number(10) primary key,
       name     varchar2(10),
       gender   number(1)  default 1,
       birthday date
);

主鍵不可重複, SCOTT.SYS_C0017981是系統自動分配的約束的名字

主鍵不可為空

我們可以自己來指定主鍵約束的名字

create table person(
       pid      number(10),
       name     varchar2(10),
       gender   number(1)  default 1,
       birthday date,
       constraint person_pk_pid primary key(pid)
);

2.非空約束

使用非空約束,可以使指定的欄位不可以為空。
範例:建立一張pid和name不可以為空的表

create table person(
       pid      number(10) not null,
       name     varchar2(10) not null,
       gender   number(1)  ,
       birthday date,
);

3.唯一約束(unique)

表中的一個欄位的內容是唯一的
範例:建表一個name是唯一的表

create table person(
       pid      number(10) ,
       name     varchar2(10) unique,
       gender   number(1)  ,
       birthday date
);

唯一約束的名字也可以自定義

create table person(
       pid      number(10) ,
       name     varchar2(10),
       gender   number(1)  ,
       birthday date,
       constraint person_name_uk unique(name)
);

4.檢查約束

使用檢查約束可以來約束欄位值的合法範圍。
範例:建立一張表性別只能是1或2

create table person(
       pid      number(10) ,
       name     varchar2(10),
       gender   number(1)  check(gender in (1, 2)),
       birthday date
);

檢查約束也可以自定義

create table person(
       pid      number(10) ,
       name     varchar2(10),
       gender   number(1),
       birthday date,
       constraint person_gender_ck check(gender in (1,2))
);

5.外來鍵約束

之前所講的都是單表的約束,外來鍵是兩張表的約束,可以保證關聯資料的完整性。
範例:建立兩張表,一張訂單表,一張是訂單明細表,訂單和明細是一對多的關係

create table orders(
       order_id      number(10) ,
       total_price   number(10,2),
       order_time date,
      constraint orders_order_id_pk primary key(order_id)
);

create table order_detail(
       detail_id      number(10) ,
       order_id   number(10),
       item_name  varchar2(10),
       quantity   number(10),
      constraint order_detail_detail_id_pk primary key(detail_id)
);

insert into orders values(1, 200, to_date('2015-12-12','yyyy-MM-dd'));
insert into order_detail values(1, 2, 'java',1);

我們在兩張表中插入如上兩條資料,我們發現在order_detail表中插入的order_id在order表中並不存在,這樣在資料庫中就產生了髒資料。此時需要外來鍵來約束它。

我們再次建表

create table orders(
       order_id      number(10) ,
       total_price   number(10,2),
       order_time date,
      constraint orders_order_id_pk primary key(order_id)
);

create table order_detail(
       detail_id      number(10) ,
       order_id   number(10),
       item_name  varchar2(10),
       quantity   number(10),
      constraint order_detail_detail_id_pk primary key(detail_id),
      constraint order_detail_order_id_fk foreign key(order_id) references orders(order_id)
);

外來鍵關聯一定注意:
外來鍵一定是主表的主鍵
刪表時一定先刪字表再刪主表,如果直接刪主表會出現由於約束存在無法刪除的問題



但是可以強制刪除drop table orders cascade constraint;(不建議)
刪除主表的資料可以刪除子表的關聯資料,再刪主表,也可以使用級聯刪除級聯刪除在外來鍵約束上要加上on delete cascade constraint order_detail_order_id_fk foreign key(order_id) references orders(order_id) on delete cascade
這樣刪除主表資料的時候會把字表的關聯資料一同刪除


7.rownum

ROWNUM:表示行號,實際上此是一個列,但是這個列是一個偽列,此列可以在每張表中出現。
範例:查詢emp錶帶有rownum列
select rownum, t.* from emp t

我們可以根據rownum來取結果集的前幾行,比如前5行

但是我們不能取到中間幾行,因為rownum不支援大於號,只支援小於號,如果想實現我們的需求怎麼辦呢?答案是使用子查詢,也正是oracle分頁的做法。
select * from (select rownum rm, a.* from (select * from emp) a where rownum < 11) b where b.rm > 5

8.檢視

檢視就是封裝了一條複雜查詢的語句。
語法1.:CREATE VIEW 檢視名稱 AS 子查詢
範例:建立一個檢視,此檢視包括了20部門的全部員工資訊
create view empvd20 as select * from emp t where t.deptno = 20

檢視建立完畢就可以使用檢視來查詢,查詢出來的都是20部門的員工

語法2:CREATE OR REPLACE VIEW 檢視名稱 AS 子查詢
如果檢視已經存在我們可以使用語法2來建立檢視,這樣已有的檢視會被覆蓋。
create or replace view empvd20 as select * from emp t where t.deptno = 20

那麼檢視可以修改嗎?

我們嘗試著修改檢視但是發現是檢視所查詢的表的欄位值被修改了。所以我們一般不會去修改檢視。
我們可以設定檢視為只讀。
語法3:CREATE OR REPLACE VIEW 檢視名稱 AS 子查詢 WITH READ ONLY
create or replace view empvd20 as select * from emp t where t.deptno = 20 with read only

9.序列

在很多資料庫中都存在一個自動增長的列,如果現在要想在oracle 中完成自動增長的功能, 則只能依靠序列完成,所有的自動增長操作,需要使用者手工完成處理。

語法:CREATE SEQUENCE 序列名 
     [INCREMENT BY n] 
     [START WITH n] 
     [{MAXVALUE/ MINVALUE n|NOMAXVALUE}] 
     [{CYCLE|NOCYCLE}] 
     [{CACHE n|NOCACHE}];

範例:建立一個seqpersonid的序列,驗證自動增長的操作
CREATE SEQUENCE seqpersonid;
序列建立完成之後,所有的自動增長應該由使用者自己處理,所以在序列中提供了以下的兩種操作:
NextVal :取得序列的下一個內容
CurrVal :取得序列的當前內容

select seqpersonid.nextval from dual;
select seqpersonid.currval from dual;

在插入資料時需要自增的主鍵中可以這樣使用

在實際專案中每一張表會配一個序列,但是表和序列是沒有必然的聯絡的,一個序列被哪一張表使用都可以,但是我們一般都是一張表用一個序列。
序列的管理一般使用工具來管理。

10.索引

索引是用於加速資料存取的資料物件。合理的使用索引可以大大降低i/o 次數,從而提高資料訪問效能。索引有很多種我們主要介紹常用的幾種:
為什麼添加了索引之後,會加快查詢速度呢?
圖書館:如果雜亂地放書的話檢索起來就非常困難,所以將書分類,然後再建一個箱子,箱子裡面放卡片,卡片裡面可以按類查詢,按姓名查或者類別查,這樣的話速度會快很多很多,這個就有點像索引。索引的好處就是提高你找到書的速度,但是正是因為你建了索引,就應該有人專門來維護索引,維護索引是要有時間精力的開銷的,也就是說索引是不能亂建的,所以建索引有個原則:如果有一個欄位如果不經常查詢,就不要去建索引。現在把書變成我們的表,把卡片變成我們的索引,就知道為什麼索引會快,為什麼會有開銷。

建立索引的語法:
建立索引:

  1. 單例索引
    單例索引是基於單個列所建立的索引,比如:
    CREATE index 索引名 on 表名(列名)
  2. 複合索引
    複合索引是基於兩個列或多個列的索引。在同一張表上可以有多個索引,但是
    要求列的組合必須不同,比如:
Create index emp_idx1 on emp(ename,job);
Create index emp_idx1 on emp(job,ename);

範例:給person表的name建立索引
create index pname_index on person(name);
範例:給person表建立一個name和gender的索引
create index pname_gender_index on person(name, gender);

索引的使用原則:

  • 在大表上建立索引才有意義
  • 在where子句後面或者是連線條件上建立索引
  • 索引的層次不要超過4層