2012-10-25 54 views
3

我想使用的功能(在PostgreSQL的):SQL函數,可以爲NULL

create type holder as (userName varchar(50), processName varchar(50), 
    dateTime timestamp, macAddress varchar(30), labName varchar(50), 
    subjectName varchar(50)); 

create or replace function returnData( 
    uName varchar(50), pName varchar(50), dTimeIn timestamp, dTimeOut timestamp, 
    macAddress MACADDR, lName varchar(50), subjectName varchar(50) 
) returns setof holder as $$ 
declare 
    r holder%rowtype; 
begin 

    for r in (SELECT DISTINCT u.name, p.process_name, i.date_time, 
       c.mac_address, l.lab_name, d.subject_name 
    FROM user u, session s, init i, process p, computer c, laboratory l, 
     class a, subject d, occur_in o 
    WHERE i.process_id = p.process_id AND i.session_id = s.session_id 
     AND s.user_id = u.user_id AND s.comp_id = c.comp_id 
     AND c.lab_id = l.lab_id AND l.lab_id = o.lab_id 
     AND o.class_id = a.class_id AND a.subject_id = d.subject_id 
     AND p.blocked = true 
     --important part now 
     AND u.name = userName AND p.name = processName 
     AND i.dateTimeIn > dTimeIn AND i.dateTimeOut < dTimeOut 
     AND c.mac_address = macAddress 
     AND l.name = lName AND d.name = subjectName 
    ) 
    loop 
     return next r; 
    end loop; 
    return; 

end; 
$$ 
language 'plpgsql'; 

我可能有一些錯別字,因爲我翻譯這英語,但實際功能的工作,只要因爲我傳遞了有效的參數。但我的用戶可能不想按用戶名過濾結果,例如。或者他可以選擇在日期之後提供數據,但不指定完成日期。 我可以做點像

... 
IF (userName IS NULL AND pName IS NULL AND ...) 
    -- query without filtering user name nor process name, 
    -- filtering or not the other parameters 
IF (userName IS NOT NULL AND pName IS NULL AND ...) 
    --filter user name, don't filter process name, 
    -- filtering or not the other parameters 
... 

依此類推。但是,如果我沒有錯,我不得不寫49個querys,因爲我有7個參數可能會或可能不會被過濾。我能做到這一點,但如果可能的話,我想通過做類似

SELECT ... 
FROM ... 
WHERE ... 
AND userName = * 

簡化我的查詢,其中*將在參數UNAME的值,如果用戶不希望過濾的用戶名。是否有可能做這樣的事情?有沒有更好的方法來做到這一點?以及如何處理這兩個時間戳?

+0

你也可以考慮在這裏使用OUTER連接。 – vyegorov

回答

3
AND (userName is null or u.name = userName) 
    AND (processName is null or p.name = processName) 
    AND (dTimeIn is null or i.dateTimeIn > dTimeIn) 
    AND (dTimeOut is null or i.dateTimeOut < dTimeOut) 
    AND (macAddress is null or c.mac_address = macAddress) 
    AND (lName is null or l.name = lName) 
    AND (subjectName is null or d.name = subjectName) 
+0

我想我的問題不清楚。我用null作爲userName測試了你的答案,它沒有返回任何東西。當傳遞null時,它應該返回給我所有的名字。 – user1531978

+0

@ user1531978這就是我的理解。發佈後,我做了一個小而重要的修改。你是第一個還是現在的? –

+1

@ user1531978我回答的是處理這個問題的一種非常常見的模式。 –

相關問題