oracle DML語句
DML語句
1、 插入資料
建立一個新表
create table new_cust as select * from customers
--使用insert語句新增行
/*
確定要插入的行所在的表
確定要插入哪些列,沒有表示所有列
確定要插入的列的值列表
*/
1、插入時注意,主鍵約束和not null約束,外來鍵約束
insert into customers(customers.customer_id,first_name,last_name,dob,phone) values
(8,'tang','long',date '1970-09-09','12345678');
INSERT INTO customers
(customer_id, first_name, last_name, dob, phone)
VALUES
(6, 'Fred', 'Brown', to_date('1970-1-1','yyyy-mm-dd'), '800-555-1215');
SELECT * FROM customers;
Not null約束
INSERT INTO customers
(customer_id, first_name, last_name, dob, phone)
VALUES
(7, '', 'Brown', to_date('1970-1-1','yyyy-mm-dd'), '800-555-1215');
SELECT * FROM customers;
2、忽略列的列表
--當為所有的列都提供值時可以忽略列的列表
--指定的值順序必須與describe命名輸出結果中顯示的列順序一致
INSERT INTO customers
VALUES
(7, 'Jane', 'Green', DATE '1970-1-1', '800-555-1216');
select * from customers
3、為列指定空值
INSERT INTO customers
VALUES
(8, 'Sophie', 'White', NULL, NULL);
4、插入預設值
INSERT INTO order_status(Order_Status_Id)
VALUES(3);
SELECT * FROM order_status;
5、在列值中使用單引號和雙引號
INSERT INTO customers
VALUES(11, 'Kyle', 'O''Malley', '', NULL);
SELECT * FROM customers;
INSERT INTO products
(product_id, product_type_id, name, description, price)
VALUES(13, 1, 'The "Greate" Gatsby', NULL, 12.99);
6、處理&
INSERT INTO products
(product_id, product_type_id, name, description, price)
VALUES
(14, 1, 'The "Greate" &&Gatsby', NULL, 12.99);
SELECT * FROM products;
7、從一個表向另外一個表複製行
select * from customers;
create table new_table as select * from customers;
delete from new_table;
select * from new_table;
insert into new_table select * from customers;
INSERT INTO customers
(customer_id, first_name, last_name)
SELECT 13, first_name, last_name FROM customers WHERE customer_id = 1;
SELECT * FROM customers;
8、主鍵衝突
--主鍵衝突
INSERT INTO customers
(customer_id, first_name, last_name, dob, phone)
VALUES
(1, 'Fred', 'Brown', DATE '1970-1-1', '800-555-1215');
--not null約束
INSERT INTO customers
(customer_id, first_name, last_name, dob, phone)
VALUES
('23', 'a', null, DATE '1970-1-1', '800-555-1215');
9、外來鍵約束
SELECT * FROM products;
SELECT * FROM product_types;
INSERT INTO products
(product_id, product_type_id, NAME, description, price)
VALUES
(13, 6, 'Nike', 'US', 88.99);
10、替換變數
INSERT INTO products
(product_id, product_type_id, NAME, description, price)
VALUES
(&pid, &type_id, '&name', 'US', 88.99);
select * from products
2、修改資料
--使用update語句修改行
/*
確定要修改的行所在的表
確定要修改哪些列及新的列值
確定要修改那些行where
*/
SELECT last_name
FROM customers
WHERE customer_id = 2;
UPDATE customers
SET last_name = 'Red'
WHERE customer_id = 2;
select * from customers
--對多列進行更新
SELECT price,NAME
FROM products
WHERE price >= 10;
UPDATE products
SET price = price * 1.2, NAME = lower(NAME)
WHERE price >= 10;
--主鍵可以更新
UPDATE products SET product_id = 13 WHERE NAME = 'My Front Line';
select * from products where NAME = 'My Front Line';
修改僱員id為1的員工的薪水等於僱員id為2的薪水
update employees e set e.salary = (select t.salary from employees t where t.employee_id =2) where e.employee_id =1
3、刪除資料
--使用delete語句刪除行
DELETE FROM products WHERE product_id = 12;
--外來鍵約束
DELETE FROM customers
WHERE customer_id = 1;
可以刪除
DELETE FROM customers
WHERE customer_id = 5;
select * from purchases
資料
select * from all_sales
delete from all_sales
rollback
4、事務與鎖
事務與鎖是兩個聯絡非常緊密的概念,它們保證了資料庫的一致性。由於資料庫是一個可以由多個使用者共享的資源,因此當多個使用者併發地存取資料時,就要保證資料的準確性。事務與鎖就是來完成這個功能的。
事務在資料庫中主要用於保證資料的一致性,防止出現錯誤資料。
在事務內的語句被作為一個整體,一個失敗,全部失敗。
事務在沒有提交前可以回滾,一旦事務提交就不能再撤銷。
什麼是事務
事務就是一組包含一條或多條語句的邏輯單元,每個事務都是一個原子單位。
--資料庫事務
--就是一組SQL語句,這組SQL語句是一個邏輯工作單元。
--事務的提交和回滾
Commit 永久性修改,提交事務
Rollback 把操作還原,回滾事務
INSERT INTO customers
VALUES
(6, 'Fred', 'Green', DATE '1970-1-1', '800-555-1215');
COMMIT;
UPDATE customers SET first_name = 'Edward' WHERE customer_id = 1;
ROLLBACK;
--事務的開始和結束
--事務開始
1)連線到資料庫,並執行一條DML語句
2)前一個事務結束後,又輸入了另外一條DML語句
--事務結束
1)執行commit或rollback語句
2)執行一條DDL語句,會自動執行commit語句
3)執行一條DCL語句,如grant語句,會自動執行commit語句。
4)斷開與資料庫的連線。會根據是否正常推出commit或rollback
5)執行了一條DML語句,該語句失敗了,會rollback
--儲存點
--在事務的任何點都能夠設定一個儲存點,這樣可以將修改回滾到儲存點處。
select * from products
UPDATE products
SET price = price * 1.20
WHERE product_id = 1;
SAVEPOINT save1;
UPDATE products
SET price = price * 1.30
WHERE product_id = 2;
SELECT product_id,price
FROM products
WHERE product_id IN (1,2);
ROLLBACK TO SAVEPOINT save1;
SELECT product_id,price
FROM products
WHERE product_id IN (1,2);
--事務的ACID特性
/*
原子性(atomicity)事務必須成組地提交或回滾
一致性(consistency)事務必須確保資料庫的狀態一致,事務開始時,資料庫的狀態是一致的,結束時,狀態也必須是一致的
隔離性(isolation)多個事務可以獨立執行,而彼此之間不會產生影響
永續性(durability)一旦事務被提交之後,資料庫的變化就會永久保留下來
*/
--併發事務
--多個使用者同時對資料庫進行互動,每個使用者都可以同時執行自己的事務。
---------T1---------------------------------------T2----------------------
SELECT * FROM customers; SELECT * FROM customers;
--------------------------------------------------------------------------
INSERT INTO customers(
customer_id,first_name,last_name)
VALUES('7','John','Price');
--------------------------------------------------------------------------
UPDATE customers
SET last_name = 'Orange'
WHERE customer_id = 2;
--------------------------------------------------------------------------
SELECT * FROM customers; SELECT * FROM customers;
--------------------------------------------------------------------------
返回結果集中包含新插入的行和修改的行。 返回結果集中不包含事務T1所插入的
行和修改後的結果。結果集還是原來的
--------------------------------------------------------------------------
COMMIT;
--------------------------------------------------------------------------
SELECT * FROM customers;
--------------------------------------------------------------------------
返回結果集中包含事務T1所插入的
行和修改後的結果
鎖
資料庫是一個龐大的多使用者資料管理系統,在多使用者的系統中,在同一時刻多個使用者同時操作某相同資源的情況,時常發生。
利用鎖可以消除多使用者操作同一資源時可能出現的隱患。
排他鎖:也叫寫鎖。事務對資料加了排他鎖,那麼其他事務將不能對該事務加任何鎖,不能讀取與訪問。
共享鎖:也叫讀鎖。該鎖模式下的資料只能被讀取。一個事務被加了共享鎖後,其他事務不能再加排他鎖,可以加共享鎖。
鎖是實現併發的主要手段,當事務提交後,會自動釋放鎖。
鎖等待與死鎖
鎖等待的演示:
開啟兩個sql*plus視窗,分別對同一個表中的同一條記錄進行操作,會出現鎖等待。
第一個視窗執行
update customers c set c.first_name ='aaaa' where c.customer_id =6;
第二個視窗執行
update customers c set c.first_name ='bbbb' where c.customer_id =6;
會出現等待現象
只有第一個視窗commit;提交後,第二個窗口才行執行下去。
死鎖:
死鎖是鎖等待的特例,通常發生在多個會話之間。
假設事務1要修改2個資源物件A,B
事務2也需要修改2個資源物件A,B
當事務1修改A時,鎖定A,修改後,等待著修改B,同時修改A,B後,然後才提交事務。
事務2修改了B,等待修改A,這時A被事務1鎖定。
最後出現了事務1等待事務2釋放資源。事務2等待事務1釋放資源,出現死鎖的現象。
示例
事務1需要修改
update customers c set c.first_name ='tom' where c.customer_id =8;
update customers c set c.first_name ='john' where c.customer_id =9;
事務2需要修改
update customers c set c.first_name ='zhansan' where c.customer_id =8;
update customers c set c.first_name ='lisi' where c.customer_id =9;
步驟1:在第一個視窗執行
update customers c set c.first_name ='tom' where c.customer_id =8;
步驟2:在第二個視窗執行
update customers c set c.first_name ='lisi' where c.customer_id =9;
步驟3:在第一個視窗執行
update customers c set c.first_name ='john' where c.customer_id =9;
步驟4:在第二個視窗執行
update customers c set c.first_name ='zhansan' where c.customer_id =8;
會出現死鎖的情況。
Oracle會自動檢測死鎖的情況,釋放一個衝突鎖,並把訊息傳遞給對方事務。此時在第一個回話視窗中會出現下面的資訊。
Oracle自動做出處理後,並重新回到鎖等待的情況。
出現鎖等待的情況,要儘快找出原因並進行處理,以免影響資料庫效能。
--在命令列裡匯出使用者的資料
exp store/[email protected] file =d:/back/store_back.dmp owner =store log =d:/back/store_exp.log
---刪除使用者
drop user store cascade;
--把我們備份的資料,再匯入某個使用者下面去
CREATE USER store2 identified by store2;
GRANT connect, resource, dba TO store2;
--imp store/[email protected] file =d:\back\store_back.dmp fromuser =store touser=store
--從一個使用者裡去匯入到另一個使用者裡面去
imp system/[email protected] file =d:\back\store_back.dmp fromuser =store touser=store2
CREATE USER store2 identified by store2;
GRANT connect, resource, dba TO store2;
---往新使用者匯入部分表
imp system/[email protected] file =d:\back\store_back.dmp fromuser =store touser=store2
tables = employees, employees2, products, divisions, jobs, product_types
---匯出部分表的命令
exp store/[email protected] file =d:/back/table/store_back.dmp
tables= employees,employees2,customers log =d:/back/table/store_exp.log
---匯入部分表
imp store2/[email protected] tables= employees,employees2,customers rows=y
file =d:/back/table/store_back.dmp