我目前在Java中有一個準備好的語句,它在我的查詢的WHERE子句中使用以下SQL語句,但是我想重新寫入一個函數來限制用戶參數傳遞給它並可能使其更有效。在包含空搜索的where子句中使用函數
(
(USER_PARAM2 IS NULL AND
(COLUMN_NAME = nvl(USER_PARAM1, COLUMN_NAME) OR
(nvl(USER_PARAM1, COLUMN_NAME) IS NULL)
)
)
OR
(USER_PARAM2 IS NOT NULL AND COLUMN_NAME IS NULL)
)
USER_PARAM1和USER_PARAM2被用戶傳遞到準備好的語句中。 USER_PARAM1表示應用程序用戶想要搜索此特定COLUMN_NAME的內容。如果用戶不包含此參數,則它將默認爲NULL。 USER_PARAM2是我允許用戶在此COLUMN_NAME上僅搜索NULL值的方式。此外,我有一些服務器邏輯,如果用戶傳入,則將USER_PARAM2設置爲「true」;如果未由用戶指定,則爲NULL。
預期的行爲是,如果聲明USER_PARAM2,則只返回NULL的COLUMN_NAME值。如果未聲明USER_PARAM2並聲明瞭USER_PARAM1,則只返回COLUMN_NAME = USER_PARAM1。如果沒有聲明用戶參數,則返回所有行。
任何人都可以幫我解決這個問題嗎? 在此先感謝...
編輯: 只是爲了澄清這是我當前查詢的外觀(沒有其他WHERE子句中陳述..)
SELECT *
FROM TABLE_NAME
WHERE (
(USER_PARAM2 IS NULL AND
(COLUMN_NAME = nvl(USER_PARAM1, COLUMN_NAME) OR
(nvl(USER_PARAM1, COLUMN_NAME) IS NULL)
)
)
OR
(USER_PARAM2 IS NOT NULL AND COLUMN_NAME IS NULL)
)
...這是我願意喜歡去......
SELECT *
FROM TABLE_NAME
WHERE customSearchFunction(USER_PARAM1, USER_PARAM2, COLUMN_NAME)
編輯#2: 好了,另一個同事幫我這...
CREATE OR REPLACE function searchNumber (pVal IN NUMBER, onlySearchForNull IN CHAR, column_value IN NUMBER)
RETURN NUMBER
IS
BEGIN
IF onlySearchForNull IS NULL THEN
IF pVal IS NULL THEN
RETURN 1;
ELSE
IF pVal = column_value THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END IF;
ELSE
IF column_value IS NULL THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END IF;
END;
...這似乎在我的初步試驗工作..
SELECT *
FROM TABLE_NAME
WHERE 1=searchNumber(USER_PARAM1, USER_PARAM2, COLUMN_NAME);
...我與它唯一的問題是 1)可能的性能問題VS複雜的SQL語句,我開始用。 2)我將不得不爲每種數據類型創建類似的函數。 但是,後者對我來說不是什麼問題。
編輯#3 2012.02.01
所以我們結束了我在下面選擇的解決方案去,在使用功能爲基礎的方法,其中代碼/查詢清潔勝過性能。我們發現基於函數的方法比使用純SQL要差6倍左右。
感謝大家爲偉大的輸入大家!
編輯#4 2012.02.14
所以回過頭來看,我注意到,在@爲@ danihp的溶液的澄清度應用虛擬表的概念艾倫的解決方案給出了清晰和性能方面非常不錯的整體解決方案。這裏是我現在有的
WITH params AS (SELECT user_param1 AS param, user_param2 AS param_nullsOnly FROM DUAL)
SELECT *
FROM table_name, params p
WHERE (nvl(p.param_nullsOnly, p.param) IS NULL --1)
OR p.param_nullsOnly IS NOT NULL AND column_name IS NULL --2)
OR p.param IS NOT NULL AND column_name = p.param --3)
)
-- 1) Test if all rows should be returned
-- 2) Test if only NULL values should be returned
-- 3) Test if param equals the column value
再次感謝您的建議和意見!
爲什麼更改爲一個函數?原生SQL雖然可能看起來很亂,但肯定會表現更好。 – 2012-01-27 17:49:25
如果你真的想要一個函數,那麼你的「customSearchFunction」必須返回一個varchar2值(例如S/N)。而你的位置將在WHERE customSearchFunction(USER_PARAM1,USER_PARAM2,COLUMN_NAME)='S' – 2012-01-27 17:54:40
正如你所說的使用一個函數可能在評估你的語句時強制進行全表掃描。如果它是一個小桌子(或小桌子的連接),這可能無關緊要,但如果它是一張大桌子,表演可能會有很多不足之處。因人而異。 – 2012-01-27 17:59:11