INSERT ALL
WHEN deptno = 10 THEN INTO dept10 SELECT *
WHEN deptno = 20 THEN INTO dept20 SELECT *
WHEN deptno = 30 THEN INTO dept30 SELECT *
WHEN job = 'CLERK' THEN INTO clerk_emp SELECT *
ELSE INTO other_emp SELECT *
SELECT * FROM emp;
INSERT FIRST
WHEN sal > 5000 THEN INTO exec_emp SELECT *
WHEN deptno = 10 THEN INTO dept10_emp SELECT *
ELSE INTO other_emp SELECT *
SELECT * FROM emp;
差異:ALL 滿足所有條件均插入 (一行可進多表);FIRST 僅進入第一個匹配分支。
SELECT SUBSTR(item_name, 1, 2) FROM product_market_price; -- 前2字符
SELECT SUBSTR('ho鮮紅的鮮花', 1, 3) FROM dual; -- 'ho鮮' (按字符計數)
-- 格式:'PROD_12345_CAT_ELECTRONICS'
SELECT
SUBSTR(str, 1, INSTR(str, '_') - 1) AS prefix,
SUBSTR(str, INSTR(str, '_') + 1, INSTR(str, '_', 1, 2) - INSTR(str, '_') - 1) AS id,
SUBSTR(str, INSTR(str, '_', 1, 3) + 1) AS suffix
FROM dual;
-- 方法 1: 子查詢 + HAVING
SELECT * FROM scott.emp
WHERE hiredate IN (
SELECT hiredate FROM scott.emp
GROUP BY hiredate HAVING COUNT(*) > 1
);
-- 方法 2: 關聯子查詢 (性能更好)
SELECT t2.* FROM scott.emp t2,
(SELECT hiredate, COUNT(*) cnt FROM scott.emp
GROUP BY hiredate HAVING COUNT(*) > 1) t1
WHERE t2.hiredate = t1.hiredate;
-- 含時分秒時:按日期分組
SELECT * FROM scott.emp
WHERE TRUNC(hiredate) IN (
SELECT TRUNC(hiredate) FROM scott.emp
GROUP BY TRUNC(hiredate) HAVING COUNT(*) > 1
);
| 參數 | 推薦值 | 調整命令 | 作用 |
|---|---|---|---|
| DB_CACHE_SIZE | 1.5-2 GB | ALTER SYSTEM SET DB_CACHE_SIZE = 2G SCOPE=SPFILE; | 數據塊緩存,影響邏輯讀性能 |
| SHARED_POOL_SIZE | 512M-1 GB | ALTER SYSTEM SET SHARED_POOL_SIZE = 1G SCOPE=SPFILE; | SQL 解析、執行計劃、字典緩存 |
| PGA_AGGREGATE_TARGET | 512M-1 GB | ALTER SYSTEM SET PGA_AGGREGATE_TARGET = 1G SCOPE=SPFILE; | 排序/雜湊/會話私有內存 |
| SGA_TARGET | 3-3.5 GB | ALTER SYSTEM SET SGA_TARGET = 3G SCOPE=SPFILE; | 自動內存管理總量 (10g+) |
| MEMORY_TARGET | 4 GB | ALTER SYSTEM SET MEMORY_TARGET = 4G SCOPE=SPFILE; | 全自動內存管理 (11g+) |
-- 1. 動態調整 (即時生效,重啟後失效)
ALTER SYSTEM SET DB_CACHE_SIZE = 2G SCOPE=MEMORY;
-- 2. 持久化調整 (重啟生效)
ALTER SYSTEM SET DB_CACHE_SIZE = 2G SCOPE=SPFILE;
-- 3. 兩者兼備 (推薦)
ALTER SYSTEM SET DB_CACHE_SIZE = 2G SCOPE=BOTH;
-- 4. 驗證
SHOW PARAMETER db_cache;
SELECT component, current_size/1024/1024 MB FROM v$sga_dynamic_components;
DECLARE
v_sql VARCHAR2(4000);
v_cnt NUMBER;
BEGIN
v_sql := 'SELECT COUNT(*) FROM ' || p_table_name || ' WHERE status = :1';
EXECUTE IMMEDIATE v_sql INTO v_cnt USING 'ACTIVE';
DBMS_OUTPUT.PUT_LINE('Active count: ' || v_cnt);
END;
DECLARE
c INTEGER;
v_cnt NUMBER;
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, 'SELECT COUNT(*) FROM ' || p_table, DBMS_SQL.NATIVE);
DBMS_SQL.DEFINE_COLUMN(c, 1, v_cnt);
DBMS_SQL.EXECUTE(c);
IF DBMS_SQL.FETCH_ROWS(c) > 0 THEN
DBMS_SQL.COLUMN_VALUE(c, 1, v_cnt);
END IF;
DBMS_SQL.CLOSE_CURSOR(c);
END;
CREATE OR REPLACE PROCEDURE archive_orders(p_months_old IN NUMBER := 12) AS
v_sql VARCHAR2(4000);
v_cnt NUMBER;
BEGIN
-- 1. 動態構建歸檔表名
v_sql := 'CREATE TABLE orders_arc_' || TO_CHAR(SYSDATE, 'YYYYMM') ||
' AS SELECT * FROM orders WHERE order_dt < ADD_MONTHS(TRUNC(SYSDATE), -' || p_months_old || ')';
EXECUTE IMMEDIATE v_sql;
-- 2. 刪除歸檔數據 (分批提交避免 UNDO 爆滿)
v_sql := 'DELETE FROM orders WHERE order_dt < ADD_MONTHS(TRUNC(SYSDATE), -' || p_months_old || ')';
LOOP
EXECUTE IMMEDIATE v_sql || ' AND ROWNUM <= 10000';
v_cnt := SQL%ROWCOUNT;
COMMIT;
EXIT WHEN v_cnt = 0;
END LOOP;
-- 3. 索引重建
EXECUTE IMMEDIATE 'ALTER INDEX idx_orders_dt REBUILD ONLINE';
DBMS_OUTPUT.PUT_LINE('Archive completed for ' || p_months_old || ' months ago.');
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END archive_orders;