首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 LIKE 限制與替代方案:LOCATE 函數實現動態模糊查詢

     編輯:DB2 教學

痛點:DB2 LIKE 不支援變量/列作為模式

在 DB2 函數或存儲過程中,常見需求是「根據傳入參數動態模糊查詢」。然而 DB2 **不允許** LIKE 後跟變量或列:

-- 錯誤示範
CREATE PROCEDURE SEARCH_BY_KEYWORD(IN P_KEYWORD VARCHAR(100))
BEGIN
    SELECT * FROM PRODUCTS WHERE NAME LIKE '%' || P_KEYWORD || '%'; -- SQL0104N
END

報錯:SQL0104N An unexpected token "P_KEYWORD" was found following "LIKE"。

解決方案:LOCATE 函數

語法

LOCATE(search_string, source_string [, start_position])
-- 返回 search_string 在 source_string 中首次出現的位置 (1-based),未找到返回 0

改寫模式對照

實戰範例:存儲函數動態檢測項目

CREATE FUNCTION GDZJ.GETNOPASS (
    ITEMNAME VARCHAR(100),
    REPORTTYPE INTEGER,
    RESULTID INTEGER
)
RETURNS INTEGER
LANGUAGE SQL
NOT DETERMINISTIC
READS SQL DATA
BEGIN ATOMIC
    DECLARE IRESULT INTEGER DEFAULT 0;
    DECLARE ICOUNT INTEGER;

    -- REPORTTYPE: 1=外單位, 0=非外單位
    IF REPORTTYPE = 1 THEN
        SET ICOUNT = (
            SELECT COUNT(1)
            FROM DETECT_END_INFO
            WHERE CHECK_OUT_UNIT_INFO_ID = RESULTID
              AND LOCATE(ITEMNAME, PROJECT_NAME) > 0  -- 動態包含查詢
        );
    ELSE
        SET ICOUNT = (
            SELECT COUNT(1)
            FROM DETECT_END_INFO
            WHERE CHECK_OUT_UNIT_INFO_ID = RESULTID
              AND LOCATE(ITEMNAME, PROJECT_NAME) > 0
        );
    END IF;

    -- 返回邏輯: 0=無項目, 1=全合格, 2=有不合格
    IF ICOUNT = 0 THEN
        RETURN 0;
    ELSE
        -- 這裡可進一步檢查是否有不合格記錄
        RETURN CASE WHEN EXISTS (
            SELECT 1 FROM DETECT_END_INFO
            WHERE CHECK_OUT_UNIT_INFO_ID = RESULTID
              AND LOCATE(ITEMNAME, PROJECT_NAME) > 0
              AND RESULT_FLAG = 'FAIL'
        ) THEN 2 ELSE 1 END;
    END IF;
END

效能考量與索引策略

  • LOCATE 無法使用普通 B-Tree 索引:會導致全表掃描。
  • 對策 1:全文索引 (DB2 Text Search / Net Search Extender) — 專為模糊/包含查詢設計。
  • 對策 2:觸發器維護關鍵字表 — 將需模糊查詢的列拆解為關鍵字存入關聯表,走等值索引。
  • 對策 3:應用層前綴過濾 — 若業務允許,改為 LIKE 'PREFIX%' 走索引範圍掃描。

進階:REGEXP_LIKE (DB2 11.1+ / Db2 on Cloud)

SELECT * FROM PRODUCTS
WHERE REGEXP_LIKE(NAME, '^.*' || :keyword || '.*$');

支援正則表達式,同樣接受變量,但同樣**無法走普通索引**,需全文索引支援。

總結

DB2 存儲程序/函數中實現動態模糊查詢,**首選 LOCATE(keyword, column) > 0** 替代 LIKE。對於大表高頻查詢,務必引入**全文索引**或**關鍵字倒排表**,避免全表掃描拖垮性能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
LIKE 模式LOCATE 等價邏輯說明
COL LIKE 'ABC%'LOCATE('ABC', COL) = 1前綴匹配
COL LIKE '%ABC'LOCATE('ABC', COL) > 0 AND LOCATE('ABC', COL) = LENGTH(COL) - LENGTH('ABC') + 1後綴匹配 (較繁瑣)
COL LIKE '%ABC%'LOCATE('ABC', COL) > 0**包含匹配 (最常用)**
COL LIKE '_ABC'LOCATE('ABC', COL) = 2單字符通配