使用SQL函数而不是SELECT的优点

时间:2014-10-31 18:47:18

标签: sql postgresql

在Postgresql 9.0数据库中,我可以使用WHERE子句中的整数(profile_id)为带有SELECT语句的网页创建URL。

过去我只是在方便的时候简单地完成了这个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 个答案:

答案 0 :(得分: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 :(得分:1)

函数感(sql函数)是封装。使用函数,SQL语句的某些片段具有名称,语义 - 您可以重用它,您可以构建库。没有任何其他好处,如性能 - 它只影响您的代码可读性。