-- 创建存储过程 CREATEOR REPLACE PROCEDURE update_salary( p_emp_id IN NUMBER, p_increase_pct IN NUMBER ) AS v_current_salary NUMBER; BEGIN SELECT salary INTO v_current_salary FROM employees WHERE employee_id = p_emp_id; UPDATE employees SET salary = salary * (1+ p_increase_pct/100) WHERE employee_id = p_emp_id; COMMIT; DBMS_OUTPUT.PUT_LINE('Salary updated successfully'); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Employee not found'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error: '|| SQLERRM); ROLLBACK; END; /
-- 创建函数 CREATEOR REPLACE FUNCTION get_employee_name( p_emp_id IN NUMBER ) RETURN VARCHAR2 IS v_full_name VARCHAR2(100); BEGIN SELECT first_name ||' '|| last_name INTO v_full_name FROM employees WHERE employee_id = p_emp_id; RETURN v_full_name; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN'Employee not found'; END; /
-- 创建触发器 CREATEOR REPLACE TRIGGER trg_employees_audit AFTER INSERTORUPDATEORDELETEON employees FOREACHROW DECLARE v_action VARCHAR2(10); BEGIN IF INSERTING THEN v_action :='INSERT'; ELSIF UPDATING THEN v_action :='UPDATE'; ELSIF DELETING THEN v_action :='DELETE'; END IF; INSERTINTO employees_audit ( employee_id, action, action_date, old_salary, new_salary ) VALUES ( :OLD.employee_id, v_action, SYSDATE, :OLD.salary, :NEW.salary ); END; /
高级查询
1. 分析函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
-- 排名函数 SELECT employee_id, first_name, salary, RANK() OVER (ORDERBY salary DESC) as salary_rank, DENSE_RANK() OVER (ORDERBY salary DESC) as dense_rank, ROW_NUMBER() OVER (ORDERBY salary DESC) as row_num FROM employees;
-- 分区分析 SELECT department_id, employee_id, first_name, salary, RANK() OVER (PARTITIONBY department_id ORDERBY salary DESC) as dept_rank, SUM(salary) OVER (PARTITIONBY department_id) as dept_total_salary FROM employees;
-- 移动平均 SELECT employee_id, hire_date, salary, AVG(salary) OVER (ORDERBY hire_date ROWSBETWEEN2 PRECEDING AND2 FOLLOWING) as moving_avg FROM employees;
-- 相关子查询 SELECT e.employee_id, e.first_name, e.salary FROM employees e WHERE e.salary > ( SELECTAVG(salary) FROM employees WHERE department_id = e.department_id );
-- 集合操作 SELECT employee_id FROM employees UNION SELECT manager_id FROM departments;
SELECT employee_id FROM employees INTERSECT SELECT manager_id FROM departments;
SELECT employee_id FROM employees MINUS SELECT manager_id FROM departments;
性能优化
1. 执行计划分析
1 2 3 4 5 6 7 8 9 10 11 12
-- 查看执行计划 EXPLAIN PLAN FOR SELECT*FROM employees e, departments d WHERE e.department_id = d.department_id AND e.salary >5000;
-- 显示执行计划 SELECT*FROMTABLE(DBMS_XPLAN.DISPLAY);
-- 使用AUTOTRACE SET AUTOTRACE ON; SELECT*FROM employees WHERE department_id =10;
2. 索引优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14
-- 创建复合索引 CREATE INDEX idx_emp_dept_salary ON employees(department_id, salary);
-- 索引提示 SELECT/*+ INDEX(employees idx_emp_dept_salary) */* FROM employees WHERE department_id =10;
-- 收集统计信息 BEGIN DBMS_STATS.GATHER_TABLE_STATS('HR', 'EMPLOYEES'); DBMS_STATS.GATHER_INDEX_STATS('HR', 'IDX_EMP_DEPT_SALARY'); END; /
3. 分区优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-- 创建分区表 CREATETABLE sales_range ( sale_id NUMBER, sale_date DATE, amount NUMBER(10,2) ) PARTITIONBYRANGE (sale_date) ( PARTITION p2023 VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD')), PARTITION p2024 VALUES LESS THAN (TO_DATE('2025-01-01', 'YYYY-MM-DD')), PARTITION pmax VALUES LESS THAN (MAXVALUE) );
-- 分区查询优化 SELECT*FROM sales_range PARTITION (p2024) WHERE sale_date BETWEEN'2024-01-01'AND'2024-12-31';