Trong bài viết này, chúng tôi sẽ xem xét một số biến thể của câu lệnh UPDATE
- Thiết lập môi trường
- COMMIT và ROLLBACK
- UPDATE cơ bản
- UPDATE qua View
- Scalar Subqueries
- 0 Rows Updated
Thiết lập
Các ví dụ trong bài viết này yêu cầu phải có các bảng sau đây.
--DROP TABLE employees PURGE;
--DROP TABLE departments PURGE;
CREATE TABLE departments (
department_id NUMBER(2) CONSTRAINT departments_pk PRIMARY KEY,
department_name VARCHAR2(14),
location VARCHAR2(13)
);
INSERT INTO departments VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO departments VALUES (20,'RESEARCH','DALLAS');
INSERT INTO departments VALUES (30,'SALES','CHICAGO');
INSERT INTO departments VALUES (40,'OPERATIONS','BOSTON');
COMMIT;
CREATE TABLE employees (
employee_id NUMBER(4) CONSTRAINT employees_pk PRIMARY KEY,
employee_name VARCHAR2(10),
job VARCHAR2(9),
manager_id NUMBER(4),
hiredate DATE,
salary NUMBER(7,2),
commission NUMBER(7,2),
department_id NUMBER(2) CONSTRAINT emp_department_id_fk REFERENCES departments(department_id)
);
INSERT INTO employees VALUES (7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20);
INSERT INTO employees VALUES (7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);
INSERT INTO employees VALUES (7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);
INSERT INTO employees VALUES (7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);
INSERT INTO employees VALUES (7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30);
INSERT INTO employees VALUES (7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30);
INSERT INTO employees VALUES (7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10);
INSERT INTO employees VALUES (7788,'SCOTT','ANALYST',7566,to_date('13-JUL-87','dd-mm-rr')-85,3000,NULL,20);
INSERT INTO employees VALUES (7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10);
INSERT INTO employees VALUES (7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30);
INSERT INTO employees VALUES (7876,'ADAMS','CLERK',7788,to_date('13-JUL-87', 'dd-mm-rr')-51,1100,NULL,20);
INSERT INTO employees VALUES (7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30);
INSERT INTO employees VALUES (7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20);
INSERT INTO employees VALUES (7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10);
COMMIT;
Các bảng này là một biến thể của các bảng EMP và DEPT từ lược đồ SCOTT. Bạn sẽ thấy rất nhiều ví dụ của Oracle trên internet bằng cách sử dụng các bảng từ lược đồ SCOTT. Bạn có thể tìm thấy các định nghĩa bảng gốc trong tập lệnh "$ ORACLE_HOME / rdbms / admin / utlsampl.sql".
COMMIT và ROLLBACK
Khi thay đổi dữ liệu để xác nhận thay đổi đó là đúng người dùng cần gõ lệnh COMMIT, khi commit dữ liệu đó sẽ được lưu vĩnh viễn trong datafile và người dùng khác có thể nhìn thấy dữ liệu thay đổi đó.
Khi chưa gõ commit nhưng có lệnh DDL thì sẽ được commit ngầm định, xác nhận tất cả các thay đổi DML nổi bật trong phiên hiện tại.
Nếu bạn quyết định không muốn giữ một số thay đổi chưa commit, bạn có thể loại bỏ chúng bằng cách sử dụng câu lệnh
ROLLBACK
để hoàn nguyên dữ liệu về trạng thái ban đầu.UPDATE cơ bản
Câu lệnh
UPDATE
được sử dụng để thay đổi các giá trị cột trong một hàng hiện có. Không có mệnh đề WHERE
, tất cả các hàng trong bảng được cập nhật bằng một câu lệnh.
Truy vấn sau đây liệt kê tất cả các giá trị SALARY trong bảng EMPLOYEE.
SELECT e.salary
FROM employees e
ORDER BY e.salary;
SALARY
----------
800
950
1100
1250
1250
1300
1500
1600
2450
2850
2975
3000
3000
5000
14 rows selected.
SQL>
Hãy cập nhật tất cả bằng câu lệnh sau:
UPDATE employees
SET salary = salary + 1;
14 rows updated.
SQL>
SELECT e.salary
FROM employees e
ORDER BY e.salary;
SALARY
----------
801
951
1101
1251
1251
1301
1501
1601
2451
2851
2976
3001
3001
5001
14 rows selected.
SQL>
Mệnh đề
WHERE
được sử dụng để giới hạn các dòng dữ liệu. Chúng ta có thể muốn cập nhật một số lượng nhỏ hàng hoặc thậm chí một hàng bằng cách sử dụng bộ lọc trên (các) cột khóa chính của bảng.UPDATE employees
SET salary = salary - 1
WHERE salary >= 2000;
6 rows updated.
SQL>
SELECT e.salary
FROM employees e
ORDER BY e.salary;
SALARY
----------
801
951
1101
1251
1251
1301
1501
1601
2450
2850
2975
3000
3000
5000
14 rows selected.
SQL>
-- Revert all the changes.
ROLLBACK;
Nhiều giá trị cột có thể được sửa đổi trong một câu lệnh
UPDATE
.UPDATE employees
SET salary = 9999,
commission = 1000,
manager_id = 7566
WHERE employee_id = 7369;
1 row updated.
SQL>
ROLLBACK;
UPDATE qua View
Có thể cập nhật bảng cơ sở được liên kết với một view.
CREATE OR REPLACE VIEW employees_v AS
SELECT * FROM employees;
UPDATE employees_v
SET salary = 1000
WHERE employee_id = 7369;
1 row updated.
SQL>
ROLLBACK;
Bạn sẽ không thấy nó rất thường xuyên, nhưng bạn cũng có thể cập nhật thông qua các inline view. Điều này có thể được sử dụng để kiểm soát số lượng hàng được cập nhật, thay vì sử dụng bộ lọc trong mệnh đề
WHERE
của câu lệnh UPDATE
.UPDATE (SELECT employee_id, salary
FROM employees
WHERE department_id = 20)
SET salary = 4000;
5 rows updated.
SQL>
ROLLBACK;
Truy vấn con vô hướng (Scalar Subqueries)
Giá trị cập nhật có thể đến từ một truy vấn con vô hướng. Phần sau đây
UPDATE
SALARY của nhân viên 7369, cho nhân viên được trả lương cao nhất.UPDATE employees
SET salary = (SELECT MAX(salary) FROM employees)
WHERE employee_id = 7369;
1 row updated.
SQL>
ROLLBACK;
Cập nhật 0 hàng
Bản cập nhật không có hàng là bản cập nhật hợp lệ và không dẫn đến lỗi. Điều này có thể gây nhầm lẫn cho người mới bắt đầu.
UPDATE employees
SET salary = 10000
WHERE employee_id = 9999;
0 rows updated.
SQL>
Do đó, bạn không thể kiểm tra lỗi không cập nhật các hàng bằng ngoại lệ
NO_DATA_FOUND
trong PL/SQL:SET SERVEROUTPUT ON
BEGIN
UPDATE employees
SET salary = 10000
WHERE employee_id = 9999;
DBMS_OUTPUT.put_line('NO_DATA_FOUND Not Raised');
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.put_line('NO_DATA_FOUND Raised');
END;
/
NO_DATA_FOUND Not Raised
PL/SQL procedure successfully completed.
SQL>
Thay vào đó, bạn phải kiểm tra thủ công số hàng được cập nhật bằng cách sử dụng
SQL%ROWCOUNT
.SET SERVEROUTPUT ON
BEGIN
UPDATE employees
SET salary = 10000
WHERE employee_id = 9999;
IF SQL%ROWCOUNT = 0 THEN
-- Manually raise the NO_DATA_FOUND exception.
RAISE NO_DATA_FOUND;
END IF;
DBMS_OUTPUT.put_line('NO_DATA_FOUND Not Raised');
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.put_line('NO_DATA_FOUND Raised');
END;
/
NO_DATA_FOUND Raised
PL/SQL procedure successfully completed.
SQL>
@ Trần Văn Bình - Founder of "Oracle DBA Việt Nam"
#OracleTutorial
#OracleDBA
#OracleDatabaseAdministration
#học oracle database
#oca
#ocp
#oce
#ocm