2014-10-31 50 views
1

在Postgresql 9.0數據庫中,我可以在WHERE子句中使用整數(profile_id)爲SELECT語句創建網頁的URL。使用SQL函數而不是SELECT的好處

在過去,我只是簡單地做了這個SELECT,只要它很方便,例如使用子查詢作爲視圖中的列/字段。但我最近意識到我可以創建一個SQL函數來做同樣的事情。 (這是一個SQL函數,不是plpgsql)。

我想知道是否有一個優勢,主要是在使用一個函數,而不是在這樣的情況下的SELECT使用的資源方面?請參閱下面的內容並提前致謝。我在本網站的其他地方找不到關於此主題的任何內容。 (長時間讀者,首次來電者)。

該功能如下。

CREATE OR REPLACE FUNCTION msurl(integer) 
RETURNS text AS 
$BODY$  
SELECT (('https://www.thenameofmywebsite/'::text || 
    CASE 
     WHEN prof.type = 1 THEN 'm'::text 
     ELSE 'f'::text 
    END) || '/handler/'::text) || prof.profile_id AS profile_url 
FROM profile prof 
WHERE prof.profile_id = $1; 
$BODY$ 
LANGUAGE sql 

爲了讓我的網址我既可以使用

SELECT prof.name,  
SELECT (('https://www.thenameofmywebsite/'::text || 
    CASE 
     WHEN prof.type = 1 THEN 'm'::text 
     ELSE 'f'::text 
    END) || '/handler/'::text) || prof.profile_id AS profile_url, prof.start_date 
FROM profile prof, 
WHERE prof.profile_id = id_number; 

或整潔的版本:

SELECT prof.name, msurl(id_number) as profile_url, prof.start_date FROM profile prof; 

回答

2

您使用該功能的方式沒有任何優勢 - 相反的情況是:它會大幅降低您的選擇速度。因爲對於從主select語句(調用函數的那個​​)檢索的每一行,您正在運行另一個在同一個表上進行選擇。

當你想封裝構建url的邏輯時,函數確實有優勢。但是,你需要以不同的方式編寫函數是由它傳遞行更有效你要使用:

CREATE OR REPLACE FUNCTION msurl(profile) 
RETURNS text AS 
$BODY$  
SELECT (('https://www.thenameofmywebsite/' || 
    CASE 
     WHEN $1.type = 1 THEN 'm' 
     ELSE 'f' 
    END) || '/handler/' || $1.profile_id:: AS profile_url; 
$BODY$ 
LANGUAGE sql; 

另一種選擇將是通過你單獨所需要的所有列,但通過傳遞如果邏輯改變並且您需要更多或更少的表中的列,則不需要更改函數簽名(並因此調用它)。

你可以接着用下面的語法調用此:

SELECT prof.name, 
     msurl((prof)) as profile_url, 
     prof.start_date 
FROM profile prof; 

注意,別名必須將它傳遞給函數時用括號括起來(prof)。附加的括號是而不是可選。

這種方式仍然爲每行調用函數,但它不運行另一個選擇profile表。

由於面向對象方法的Postgres對待這樣,你甚至可以調用它,因爲它是表中的列的函數:

SELECT prof.name, 
     prof.msurl as profile_url, 
     prof.start_date 
FROM profile prof; 
1

檢測功能(SQL函數)的封裝。通過函數,您的SQL語句的某些片段具有名稱,語義 - 您可以重用它,您可以構建一個庫。沒有任何其他好處像性能 - 它隻影響你的代碼可讀性。

+0

在這個例子中功能*會*對性能有很大的影響這是由於結果中每行都進行了額外的選擇。 – 2014-11-01 08:06:33

+0

它可以用STABLE標誌內聯,但是在評論中有一個true。更好的喲寫沒有完整的內部SELECT只是標量SQL函數 – 2014-11-01 09:40:27

相關問題