简体   繁体   English

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

[英]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.

相关问题 简化SQL查询,而不是使用联接 - Simplify SQL query rather than using Joins Advantage SQl中的Datediff函数 - Datediff function in Advantage SQl 从 python 函数中返回 DataFrame 而不是使用 Pandas 的 pd.read_sql_query 列表 - Return DataFrame from within python function rather than list using pandas' pd.read_sql_query 如果所有SQL都在执行SELECT,那么使用视图和SPROC是否有优势 - If all SQL is doing is SELECT, is there an advantage to using a view vs a SPROC Access SQL:选择最近的日期而不是日期列表 - Access SQL: Select most recent date rather than list of dates 管理代码而不是数据库中的级联删除是否有任何真正的优势? - Is there any real advantage to managing cascading deletes in code rather than the DB? SAS SQL连接表基于函数而不是变量匹配 - SAS sql join tables based on function rather than variable match INSERT INTO sql查询使用变量字符串而不是字段名称 - INSERT INTO sql query is using variable string rather than field name 在SQL Server中使用联接而不是子查询 - using Joins rather than sub queries in SQL Server 如何在Oracle中使用WITH而不是CONNECT BY来获取递归SQL的深度? - How to get depth of recursive SQL using WITH rather than CONNECT BY in Oracle?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM