2016-05-30 81 views
1

是否有通用模式來創建帶有可選參數的搜索查詢?我在想,我們應該能夠構建一個多部分where子句,但是將沒有指定的部分取消。另外一些查詢參數可能需要連接,如果沒有指定關聯的查詢參數,我想取消它們。如何使用可選搜索參數在SQL中創建搜索查詢?

(見全碼here

認爲一個人手域組成。它由項目,需求,人員和技能組成。我們想搜索基於以下標準要求:

1. min_start_date 
2. max_start_date 
3. project_id 
4. project_location 
5. skill_id 

下面是相關表格:

CREATE TABLE projects (
    id SERIAL PRIMARY KEY, 
    name VARCHAR(64), 
    location VARCHAR(3) NOT NULL 
); 

CREATE TABLE needs (
    id SERIAL PRIMARY KEY, 
    start_date TIMESTAMPTZ, 
    end_date TIMESTAMPTZ, 
    project_id INTEGER NOT NULL, 
    skill_id INTEGER NOT NULL 
); 

CREATE TABLE skills (
    id SERIAL PRIMARY KEY, 
    name VARCHAR(64) NOT NULL 
); 

下面是搜索查詢:

\set min_start_date '2016-08-01T00:00:00-04' 
\set max_start_date '2016-08-31T00:00:00-04' 
\set project_id 71 
\set project_location 'DEN' 
\set skill_id 4 

SELECT n.id, n.start_date, n.end_date 
FROM needs n 
     LEFT OUTER JOIN projects p 
        ON n.project_id = p.id 
WHERE n.start_date >= :'min_start_date' 
    AND n.start_date < :'max_start_date' 
    AND p.id = :'project_id' 
    AND p.location = :'project_location' 
    AND s.id = :'skill_id' 
ORDER BY n.start_date, p.id, s.id; 

我想要什麼取決於指定哪個查詢參數,能力使where子句的部分無效。如果未指定搜索參數project_location,則不需要執行連接。

編輯

基於尼爾·麥圭根的評論,我想這一點:

\set min_start_date 2016-08-01T00:00:00-04 

SELECT * 
FROM needs n 
WHERE (:'min_start_date' IS NULL OR n.start_date >= :'min_start_date'); 

這正常工作,併產生期望的結果,但是當我改變min_start_date爲NULL值:

\set min_start_date NULL 

我從PostgreSQL得到以下錯誤:

ERROR: invalid input syntax for type timestamp with time zone: "NULL" 
LINE 8: WHERE ('NULL' IS NULL OR n.start_date >= 'NULL') 
               ^

基本上我無法爲OR的兩側提供正確的類型。不知道如何指定NULL參數值並且SQL語句可能工作。

+0

如果你不需要的PARAMS提供NULL值,這肯定是有可能使其複雜,但你應該動態地生成查詢並且不包括那些部分。 –

+0

當你說*動態生成查詢*你的意思是字符串連接每次產生一個自定義查詢?那意味着根本沒有準備好的陳述,對嗎?我希望能有更好的辦法。 – Naresh

+1

您似乎在引用您的綁定變量 - 沒有必要 - 您正在檢查字符串「NULL」是否爲NULL,或者日期是否大於或等於字符串。 – Ben

回答

0

是:

where 
    (column1Value is null OR column1 = column1Value) 
    and (column2Value is null OR column2 = column2Value) 
    ... 

而一個連接條件是任何舊的謂語,所以你可以只要你喜歡

+0

謝謝尼爾。這很棒。我幾乎可以看到它的工作。但是,當我嘗試它時,PostgreSQL將引號置爲NULL,並將其解釋爲一個字符串。請參閱上面的編輯以及錯誤消息。 – Naresh

+1

看來,psql變量只是字符串替換(如宏)。它們不是具有類型的頭等變量。我認爲當我用編程語言做這件事時,我可以使你的基本概念有效。標記你的答案是正確的。 – Naresh