[英]Advantage of using a SQL function rather than a SELECT
In a Postgresql 9.0 database, I can create a url for a webpage with a SELECT statement using an integer (profile_id) in the WHERE clause. 在Postgresql 9.0数据库中,我可以使用WHERE子句中的整数(profile_id)为带有SELECT语句的网页创建URL。
In the past I've simply done this SELECT whenever it is convenient, for instance using a subquery as a column/field in a view. 在过去,我只是在方便时完成SELECT,例如使用子查询作为视图中的列/字段。 But I recently realized I could create a SQL function to do the same thing.
但我最近意识到我可以创建一个SQL函数来做同样的事情。 (This is a SQL function, NOT plpgsql).
(这是一个SQL函数,而不是plpgsql)。
I want to know if there is an advantage , mostly in terms of resources that are being spent, in using a function rather than a SELECT in a case like this? 我想知道在这样的情况下,在使用函数而不是SELECT时是否有优势 (主要是在资源方面)? See below and thanks in advance.
见下文并提前感谢。 I could not find anything on this topic elsewhere on this site.
我在本网站的其他地方找不到关于此主题的任何内容。 (Long-time reader, first-time caller).
(长期读者,第一次来电)。
The function is below. 功能如下。
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
To get my url I can either use 为了得到我的网址,我可以使用
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;
OR the tidier version: 或更整洁的版本:
SELECT prof.name, msurl(id_number) as profile_url, prof.start_date FROM profile prof;
The way you are using the function will not have any advantage - the opposite is the case: it will slow down your select drastically. 您使用该功能的方式没有任何优势 - 情况恰恰相反:它会大大减慢您的选择。 Because for each row that is retrieved from the main
select
statement (the one calling the function) you are running another select on the same table. 因为对于从主
select
语句(调用该函数的语句)检索的每一行,您在同一个表上运行另一个 select。
Functions do have an advantage when you want to encapsulate the logic of building the url. 当您想要封装构建URL的逻辑时,函数确实有优势。 But you need to write the function differently to be more efficient by passing it the row you want to work with:
但是你需要以不同的方式编写函数,以便通过传递你想要使用的行来提高效率:
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;
Another option would have been to pass all columns that you need separately, but by passing the row (type) the function signature (and thus calls to it) will not need to be changed if the logic changes and you need more or less columns from the table. 另一种选择是传递你需要的所有列,但是通过传递行(类型)函数签名(因而调用它),如果逻辑发生变化并且你需要更多或更少的列,则不需要更改桌子。
You can then call this with the following syntax: 然后,您可以使用以下语法调用它:
SELECT prof.name,
msurl( (prof) ) as profile_url,
prof.start_date
FROM profile prof;
Note that the alias must be enclosed in parentheses (prof)
when passing it to the function. 请注意,将别名传递给函数时,必须将别名括在括号
(prof)
。 The additional parentheses are not optional here. 附加括号在此处不是可选的。
That way the function still gets called for each row, but it doesn't run another select on the profile
table. 这样,仍然会为每一行调用该函数,但它不会在
profile
表上运行另一个 select。
Due to the object oriented way Postgres treats such a function you can even call it as it it was a column of the table: 由于面向对象的方式Postgres处理这样一个函数你甚至可以调用它,因为它是表的一列:
SELECT prof.name,
prof.msurl as profile_url,
prof.start_date
FROM profile prof;
Sense of functions (sql functions) is encapsulation. 函数感(sql函数)是封装。 With functions some fragments of your SQL statements has name, semantics - you can reuse it, you can build a libraries.
使用函数,SQL语句的某些片段具有名称,语义 - 您可以重用它,您可以构建库。 There are no any other benefits like performance - it has impact just only on your code readability.
没有任何其他好处,如性能 - 它只影响您的代码可读性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.