首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 獲取表所有列名並以逗號分隔:SYS_CONNECT_BY_PATH 實現

     編輯:MySQL 資料庫相關知識

需求場景

動態構建 SELECT col1, col2, ...、INSERT INTO t (col1, col2, ...)、比對兩表結構差異等,需將列名聚合為逗號分隔字符串。

核心語法(Oracle 9i+)

SELECT MAX(SUBSTR(SYS_CONNECT_BY_PATH(COLUMN_NAME, ','), 2)) AS cols
FROM (
    SELECT COLUMN_NAME, COLUMN_ID
    FROM USER_TAB_COLUMNS
    WHERE TABLE_NAME = UPPER('&表名')
)
START WITH COLUMN_ID = 1
CONNECT BY COLUMN_ID = PRIOR COLUMN_ID + 1;

原理解析

  • SYS_CONNECT_BY_PATH(col, '/'):層次查詢函數,返回從根節點到當前節點的路徑字符串(如 /COL1/COL2/COL3)
  • START WITH COLUMN_ID = 1:以第一列為根
  • CONNECT BY COLUMN_ID = PRIOR COLUMN_ID + 1:按列 ID 遞歸串聯
  • SUBSTR(..., 2):去除首字符分隔符
  • MAX():取最深層級(最後一行)的完整路徑

替代方案對比

方法版本要求優點缺點
LISTAGG(COLUMN_NAME, ',') WITHIN GROUP (ORDER BY COLUMN_ID)11gR2+語法簡潔、性能好舊版本不支持
WM_CONCAT(COLUMN_NAME)10g+無需層次查詢非文檔函數、可能被移除
XMLAGG(XMLELEMENT(...)).EXTRACT('//text()')9i+標準 SQL/XML語法繁瑣
PL/SQL 循環拼接所有版本邏輯可控需寫函數/塊

實用封裝:可復用函數

CREATE OR REPLACE FUNCTION get_table_columns(p_table_name VARCHAR2)
RETURN CLOB IS
    v_cols CLOB;
BEGIN
    SELECT LISTAGG(COLUMN_NAME, ',') WITHIN GROUP (ORDER BY COLUMN_ID)
    INTO v_cols
    FROM USER_TAB_COLUMNS
    WHERE TABLE_NAME = UPPER(p_table_name);
    RETURN v_cols;
EXCEPTION
    WHEN NO_DATA_FOUND THEN RETURN NULL;
END;
/
-- 調用
SELECT get_table_columns('EMP') FROM DUAL;

跨 Schema 查詢

-- 替換 USER_TAB_COLUMNS 為 ALL_TAB_COLUMNS 或 DBA_TAB_COLUMNS
SELECT ... FROM ALL_TAB_COLUMNS WHERE OWNER = 'SCOTT' AND TABLE_NAME = 'EMP'

總結

Oracle 9i/10g 環境下,SYS_CONNECT_BY_PATH 是純 SQL 獲取逗號分隔列名的標準做法;11gR2+ 首選 LISTAGG。封裝為函數便於重複調用,提升開發效率。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved