当前位置:网站首页>Stored procedures of PostgreSQL
Stored procedures of PostgreSQL
2022-06-27 18:46:00 【Ink Sky Wheel】
stay PostgreSQL in , Process language ( for example PL/pgSQL,C,Perl,Python and Tcl) It is called a stored procedure . This process adds many process elements , For example, control structure , Loops and complex calculations , In order to expand SQL standard . It enables you to PostgreSQL Develop complex functions and stored procedures in , And this is using ordinary SQL May not be possible .
Here we will focus on Oracle PL/SQL alike PL/pgSQL Process language . Here are the options PL/pgSQL Why :
PL/pgSQL Easy to learn .
PostgreSQL Default with PL/pgSQL. stay PL/pgSQL User defined functions developed in can be used like any built-in function .
PL/pgSQL It has many functions , Allows you to develop complex user-defined functions .
1. introduction
PostgreSQL Various process language elements are allowed ( It is often called a stored procedure ) Use user-defined functions and stored procedures to extend database functionality .
A stored procedure defines a function for creating triggers or a custom aggregation function . Besides , Stored procedures also add a number of procedural functions , Such as control structures and complex calculations . These make it easier , Develop custom features more effectively .
have access to DO Command call procedure code block , There is no need to define functions or stored procedures .
PostgreSQL Process languages are divided into two categories :
Any user can use the security language .SQL and PL/pgSQL It's the language of security .
Sandboxed languages are used only by super users , Because sandboxed languages provide the ability to bypass security and allow access to external sources .C Is an example of a sandbox language .
By default ,PostgreSQL Three process languages are supported :SQL,PL/pgSQL and C. You can also use extensions to integrate other process languages ( for example Perl,Python and TCL) Load into PostgreSQL in .
1.1、 Use PostgreSQL Advantages of stored procedures
Reduce the number of round trips between the application and the database server . all SQL Statements are packaged and stored in PostgreSQL Functions in the database server , Therefore, the application only needs to issue a function call to return the result , You don't have to send multiple SQL Statement and wait for the result between calls .
Since user-defined functions and stored procedures have been precompiled and stored in PostgreSQL In the database server , Therefore, the application performance is improved .
Reusable in many applications . Once the functionality is developed , You can reuse it in any application .
1.2、 Use PostgreSQL Disadvantages of stored procedures
Because stored procedure programming requires many professional skills that developers do not have , So the speed of software development is slow .
Difficult to manage versions and debug .
You may not be able to migrate to other database management systems , for example MySQL or Microsoft SQL Server.
2.PL/pgSQL Block structure
PL/pgSQL Is a block structured language , therefore ,PL/pgSQL Functions or stored procedures are organized into blocks .
2.1、PL/pgSQL The grammar of
[ <<label>> ]
[ DECLARE
declarations ]
BEGIN
statements;
...
END [ label ];
Each block has two parts : Statement and body . The declaration section is optional , The main part is required . The block is marked with END Semicolon after keyword (;) ending .
The beginning and end of the block may have optional labels . If you want to EXIT Specify it in the statement of the block body , Or to qualify the name of the variable declared in the block , Please use block labels .
In the declaration section , You can declare all variables used in the body section . Each statement in the declaration section is preceded by a semicolon (;) ending .
The body is where you put the code . Each statement in the body section is also marked with a semicolon (;) End .
2.2、PL/pgSQL Block structure example
Anonymous block
test=# DO $$
<<first_block>>
DECLARE
counter integer := 0;
BEGIN
counter := counter + 1;
RAISE NOTICE 'The current value of counter is %', counter;
END first_block $$;
Be careful : The current value of counter is 1
DO
Please note that ,DO Statement does not belong to the block . It is used to execute anonymous blocks .
In the declaration section , Declared a variable counter And set its value to zero .
Inside the main body , Increase the value of the counter to 1 And use RAISE NOTICE Statement outputs its value .
first_block The label is for demonstration purposes only . In this example , It does nothing .
Double dollar ($$) Is single quotes (') An alternative . Development PL/pgSQL block , Function or stored procedure , Its body must be passed as a string literal . If you use double dollars ($$), You can avoid reference problems . You can also visit $$ Use tokens between , for example $function$ or $procedure$.
2.3、PL/pgSQL Subblock
PL/pgSQL Allows you to place one block within the host of another . A block nested within another block is called a sub block . A block that contains sub blocks is called an external block .
Subblocks are used to group statements , So that large blocks can be divided into smaller and more logical sub blocks . Variables in a sub block can have the same name as variables in an external block , Even if it's not a good habit .
When a variable with the same name as that in the external block is declared in the sub block , Variables in external blocks are hidden in sub blocks . If you want to access variables in an external block , Use a block label to qualify its name , This is shown in the following example :
test=# DO $$
<<outer_block>>
DECLARE
counter integer := 0;
BEGIN
counter := counter + 1;
RAISE NOTICE 'The current value of counter is %', counter;
DECLARE
counter integer := 0;
BEGIN
counter := counter + 10;
RAISE NOTICE 'The current value of counter in the subblock is %', counter;
RAISE NOTICE 'The current value of counter in the outer block is %', outer_block.counter;
END;
RAISE NOTICE 'The current value of counter in the outer block is %', counter;
END outer_block $$;
Be careful : The current value of counter is 1
Be careful : The current value of counter in the subblock is 10
Be careful : The current value of counter in the outer block is 1
Be careful : The current value of counter in the outer block is 1
DO
First , We are outer_block A statement named counter The variable of .
Next , In a sub block , We also declare a variable with the same name .
then , Before entering the sub block , The value of the counter is 1. In a sub block , We increase the value of the counter to 10 And print it out . Be careful , The change affects only the counter variables in the sub block .
after , We use block labels to reference counter variables in external blocks , To qualify its name external_block.counter.
Last , We print out the value of the counter variable in the external block , Its value remains unchanged .
3.PL/pgSQL Variable
PL/pgSQL Variables are meaningful names for memory locations . A variable holds a value that can be changed by a block or function . Variables are always associated with specific data types .
Before using variables , Must be in PL/pgSQL Block is declared in the declaration section of the . Syntax for declaring variables :
variable_name data_type [:= expression];
First , Specify the name of the variable . It is a good habit to assign meaningful names to variables . for example , You should use index or i Substitute named variable counter.
secondly , Associate a specific data type with a variable . The data type can be any valid PostgreSQL data type , for example INTEGER,NUMERIC,VARCHAR and CHAR.
Third , Optionally assign default values to variables . If you don't do that , The initial value of the variable will be initialized to NULL.
Declare and initialize various variables
DO $$
DECLARE
counter INTEGER := 1;
first_name VARCHAR(50) := 'John';
last_name VARCHAR(50) := 'Doe';
payment NUMERIC(11,2) := 20.5;
BEGIN
RAISE NOTICE '% % % has been paid % USD', counter, first_name, last_name, payment;
END $$;
counter Variables are initialized to 1 The integer of
first_name and last_name yes VARCHAR,50 Characters , And initialization John and Doe Text string .
payment There are two decimal numbers and initialization 20.5
Please note that , When the block is entered ,PostgreSQL Default values will be evaluated and set for variables .
test=# DO $$
DECLARE
created_at time := NOW();
BEGIN
RAISE NOTICE '%', created_at;
PERFORM pg_sleep(10);
RAISE NOTICE '%', created_at;
END $$;
Be careful : 23:07:05.060536
Be careful : 23:07:05.060536
DO
First , Declare a variable , Its default value is initialized to the current time .
secondly , Print out the value of the variable and put it in 10 Pause execution within seconds
Third , Print it out again created_at The value of the variable .
3.1、 Copy data type
PostgreSQL Allows you to define variables of a data type , This data type refers to the data type of the column of the table or the data type of another variable :
variable_name table_name.column_name%TYPE;
variable_name variable%TYPE;
Define a variable city_name, Its name name And city The column names of the tables are the same , The data types are as follows :
city_name city.name%TYPE := 'San Francisco';
By using the copy type function , You can get the following benefits :
First , You don't have to worry about the data type of the column . You declare a variable to keep only the value of that column in the query .
secondly , When the data type of a column changes , You do not need to change the variable declaration in the function to adapt to the new changes .
Third , Because the type of internal variables can be changed from one call to another , So you can reference the type of a variable as the data type of a function parameter to create a polymorphic function .
3.2、 Assign aliases to variables
PostgreSQL Allows you to define aliases for any variable , As shown below :
new_name ALIAS FOR old_name;
Alias is mainly used in triggering process , In order to have a predetermined name for ( for example NEW or OLD) To assign more meaningful names to variables .
4.PL/pgSQL Constant
Different from variables , The value of a constant cannot be changed once initialized . Here are the reasons for using constants :
First , Constants make the code more readable . for example , Suppose we have a formula as follows :
price = net_price * 0.8;
0.8 What does that mean? ? It can be interpreted as anything . however , We can give it the meaning of discount :
price = net_price * ZK;
secondly , Constants reduce maintenance , Suppose you have a formula in the function to calculate the price . When the discount is from, for example 0.8 Change to 0.9 when , You need to change all these hard coded values . however , By using constants , You only need to make changes in one place to declare and initialize constants .
4.1、 Declare constant syntax
To be in PL/pgSQL Declare a constant in , Please use the following syntax :
constant_name CONSTANT data_type := expression;
First , Specify constant name . By convention , It is capitalized , for example ZK and DISCOUNT.
secondly , place CONSTANT Keyword and specify the data type associated with the constant .
Third , Initializing a value for a constant .
4.2、PL/pgSQL Constant example
Declare a name for the discount zk The constant , And calculate the selling price according to the net price :
test=# DO $$
DECLARE
ZK CONSTANT NUMERIC := 0.8;
net_price NUMERIC := 50;
BEGIN
RAISE NOTICE 'The price is %', net_price * ZK ;
END $$;
Be careful : The price is 40.0
DO
Now? , An error occurred while trying to change the value of a constant as follows :
test=# DO $$
DECLARE
ZK constant NUMERIC := 0.8;
net_price NUMERIC := 50;
BEGIN
RAISE NOTICE 'The price is %', net_price * ZK ;
ZK := 0.85;
END $$;
error : Variable "zk" Declared as a constant
LINE 7: ZK := 0.85;
^
Be careful , When the block is entered at run time instead of compile time ,PostgreSQL The value of an accounting constant .
test=# DO $$
DECLARE
start_at CONSTANT time := now();
BEGIN
RAISE NOTICE 'Start executing block at %', start_at;
END $$;
Be careful : Start executing block at 11:38:34.260159
DO
Every time we call the block ,PostgreSQL City assessment NOW() function . To prove it , We execute the block again :
test=# DO $$
DECLARE
start_at CONSTANT time := now();
BEGIN
RAISE NOTICE 'Start executing block at %', start_at;
END $$;
Be careful : Start executing block at 11:39:52.209155
DO
5.PL/pgSQL Errors and messages
To send a message , Please use RAISE sentence :
RAISE level format;
stay RAISE Statement is followed by a level option that specifies the severity of the error .PostgreSQL There are the following levels :
DEBUG( debugging )
LOG( journal )
NOTICE( Be careful )
INFO( Information )
WARNING( Warning )
EXCEPTION( exception )
If you do not specify a level , By default ,RAISE Statement will use EXCEPTION Level , This raises an error and stops and stops the current transaction .
The format is a string that specifies the message . This format uses percentage (%) Place holder , These placeholders will be replaced by the next parameter . The number of placeholders must match the number of parameters , otherwise ,PostgreSQL An error message will be reported .
The following example illustrates RAISE sentence , This statement reports different messages at the current time :
test=# DO $$
BEGIN
RAISE INFO 'information message %', now() ;
RAISE LOG 'log message %', now();
RAISE DEBUG 'debug message %', now();
RAISE WARNING 'warning message %', now();
RAISE NOTICE 'notice message %', now();
END $$;
Information : information message 2019-12-03 12:03:41.136714+08
Warning : warning message 2019-12-03 12:03:41.136714+08
Be careful : notice message 2019-12-03 12:03:41.136714+08
DO
Please note that , Not all messages are reported to the client , Only INFO,WARNING and NOTICE Level messages are reported to the client . This is due to client_min_messages and log_min_messages Configure parameter control .
5.1、PL/pgSQL Raise an error message
To raise an error message , Please be there. RAISE Use... After the statement EXCEPTION Level . Please note that ,RAISE Statement uses... By default EXCEPTION Level .
In addition to causing an error message , You can also do it in RAISE Statement to add more details :
USING option = expression
MESSAGE: Set error message text
HINT: Provide prompt information , To make it easier to find the root cause of the error .
DETAIL: Provide details about the error .
ERRCODE: Identify the error code , You can use a condition name or a directly five character SQLSTATE Code .
Causes duplicate email error messages :
test=# DO $$
DECLARE
email varchar(255) := '[email protected]';
BEGIN
-- check email for duplicate
-- ...
-- report duplicate email
RAISE EXCEPTION 'Duplicate email: %', email
USING HINT = 'Check the email again';
END $$;
error : Duplicate email: [email protected]
HINT: Check the email again
CONTEXT: stay RAISE Of the 8 Yes PL/pgSQL function inline_code_block
The following example shows how to trigger SQLSTATE And its corresponding conditions :
DO $$
BEGIN
--...
RAISE SQLSTATE '2210B';
END $$;
DO $$
BEGIN
--...
RAISE invalid_regular_expression;
END $$;
5.2、 Use ASSERT Statement for debugging checks
ASSERT Sentence syntax
ASSERT condition [, message];
The condition is a Boolean expression . If the condition is evaluated as TRUE, be ASSERT Statement does nothing . If the condition is evaluated as FALSE or NULL, The cause ASSERT_FAILURE.
If this message is not provided , be PL/pgSQL By default “ Assertion failed ” news . If this message is provided , be ASSERT Statement will use it to replace the default message .
6.CREATE FUNCTION sentence
6.1、CREATE FUNCTION Sentence syntax
To be in PostgreSQL Create a new user-defined function in , Please use CREATE FUNCTION sentence :
CREATE FUNCTION function_name(p1 type, p2 type)
RETURNS type AS
BEGIN
-- logic
END;
LANGUAGE language_name;
First , stay CREATE FUNCTION Keyword to specify the name of the function .
then , Put a comma separated parameter list in parentheses after the function name .
Next , stay RETURNS Keyword to specify the return type of the function .
after , Put the code in BEGIN and END In block . The function is always preceded by a semicolon (;) ending , Heel END keyword .
Last , In the use of PL/pgSQL Under the circumstances , A procedural language that describes functions , for example plpgsql.
6.2、CREATE FUNCTION Statement example
Develop a program called inc A very simple function of , This function increments an integer by 1 And return the result .
test=# CREATE FUNCTION inc(val integer) RETURNS integer AS $$
BEGIN
RETURN val + 1;
END; $$
LANGUAGE PLPGSQL;
CREATE FUNCTION
Provide to CREATE FUNCTION The entire function definition of must be a single quoted string . This means that if the function has any single quotation marks ('), It must be escaped .
PostgreSQL There is provided a type called “$” The function of , This feature allows you to select an appropriate string , So you don't have to escape it .
If the function is valid , be PostgreSQL The function is created and returns CREATE FUNCTION sentence , As shown above .
Call function :
test=# SELECT inc(20);
inc
-----
21
(1 row)
test=# SELECT inc(inc(20));
inc
-----
22
(1 row)
7.PL/pgSQL Function parameter
7.1、PL/pgSQL IN Parameters
From create a file named get_sum() The new function of :
test=# CREATE OR REPLACE FUNCTION get_sum(
a NUMERIC,
b NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
RETURN a + b;
END; $$
LANGUAGE plpgsql;
CREATE FUNCTION
get_sum() The function takes two arguments :a and b And return a number . The data type of these two parameters is NUMERIC. By default ,PostgreSQL The parameter type of any parameter in is IN Parameters . Can be IN Parameters are passed to functions , But they cannot be retrieved as part of the result .
test=# SELECT get_sum(10,20);
get_sum
---------
30
(1 row)
7.2、PL/pgSQL OUT Parameters
OUT Parameters are defined as part of the function parameter list , And return as part of the result .
To define the OUT Parameters , Please use OUT keyword , This is shown in the following example :
test=# CREATE OR REPLACE FUNCTION abc(
a NUMERIC,
b NUMERIC,
c NUMERIC,
OUT high NUMERIC,
OUT low NUMERIC)
AS $$
BEGIN
high := GREATEST(a,b,c);
low := LEAST(a,b,c);
END; $$
LANGUAGE plpgsql;
CREATE FUNCTION
abc Function acceptance 5 Parameters :
Three IN Parameters :a,b,c.
Two OUT Parameters :high( high ) and low( low ).
Inside the function , Use GREATEST and LEAST The built-in function can get the maximum and minimum three IN Parameters . Because we use OUT Parameters , So we don't need RETURN sentence .OUT Arguments are useful in functions that need to return multiple values without defining custom types .
The following statement calls abc function :
test=# SELECT abc(10,20,30);
abc
---------
(30,10)
(1 row)
The output is separated into columns , Please use the following syntax :
test=# SELECT * FROM abc(10,20,30);
high | low
------+-----
30 | 10
(1 row)
7.3、PL/pgSQL INOUT Parameters
INOUT Parameter is IN and OUT Combination of parameters . This means that the caller can pass the value to the function . then , Function to change parameters , And return the value as part of the result .
The following example shows the square function , This function takes a number and returns the square of that number :
test=# CREATE OR REPLACE FUNCTION square(
INOUT a NUMERIC)
AS $$
BEGIN
a := a * a;
END; $$
LANGUAGE plpgsql;
CREATE FUNCTION
test=# SELECT square(4);
square
--------
16
(1 row)
7.4、PL/pgSQL VARIADIC Parameters
PostgreSQL Function can accept a variable number of arguments , But the condition is that all parameters have the same data type . Parameters are passed to the function as an array . See the following example :
test=# CREATE OR REPLACE FUNCTION sum_avg(
VARIADIC list NUMERIC[],
OUT total NUMERIC,
OUT average NUMERIC)
AS $$
BEGIN
SELECT INTO total SUM(list[i])
FROM generate_subscripts(list, 1) g(i);
SELECT INTO average AVG(list[i])
FROM generate_subscripts(list, 1) g(i);
END; $$
LANGUAGE plpgsql;
CREATE FUNCTION
test=# SELECT * FROM sum_avg(10,20,30);
total | average
-------+---------------------
60 | 20.0000000000000000
(1 row)
8.PL/pgSQL function overloading
PostgreSQL Allow multiple functions to have the same name , As long as the parameters are different . If multiple functions have the same name , These functions are overloaded . When you call a function ,PostgreSQL Determine the exact function being called according to the input parameters .
get_rental_function Function acceptance p_customer_id As a parameter . It returns a lease to a specific customer DVD Total duration of ( In days ). for example , We can get customers ID by 232 The lease term of the customer , We call get_rental_duration function , As shown below :
test=# CREATE OR REPLACE FUNCTION get_rental_duration(p_customer_id INTEGER)
RETURNS INTEGER AS $$
DECLARE
rental_duration INTEGER;
BEGIN
-- get the rate based on film_id
SELECT INTO rental_duration SUM( EXTRACT( DAY FROM return_date - rental_date))
FROM rental
WHERE customer_id=p_customer_id;
RETURN rental_duration;
END; $$
LANGUAGE plpgsql;
CREATE FUNCTION
test=# SELECT get_rental_duration(232);
get_rental_duration
---------------------
90
(1 row)
Suppose we want to know the lease term of the customer from a specific date to the present . We can do it in get_retal_duration() Add another parameter to the function p_from_date, Or you can develop a new function with the same name but two arguments , As shown below :
test=# CREATE OR REPLACE FUNCTION get_rental_duration(p_customer_id INTEGER, p_from_date DATE)
RETURNS INTEGER AS $$
DECLARE
rental_duration integer;
BEGIN
-- get the rental duration based on customer_id and rental date
SELECT INTO rental_duration
SUM( EXTRACT( DAY FROM return_date + '12:00:00' - rental_date))
FROM rental
WHERE customer_id= p_customer_id AND
rental_date >= p_from_date;
RETURN rental_duration;
END; $$
LANGUAGE plpgsql;
CREATE FUNCTION
This function has the same name as the first function , It just has two parameters . We said get_rental_duration(integer) Function is get_rental_duration(integer,date) function overloading . The following statement is obtained from 2005 year 7 month 1 From the day of, the customer ID by 232 The lease term of the customer :
test=# SELECT get_rental_duration(232,'2005-07-01');
get_rental_duration
---------------------
85
(1 row)
Be careful , If we ignore the second parameter ,PostgreSQL The first function... Will be called .
PL/pgSQL Function overloading and default values
stay get_rental_duration(integer,date) Function , If we want to add a default value for the second parameter , As shown below :
test=# CREATE OR REPLACE FUNCTION get_rental_duration(
p_customer_id INTEGER,
p_from_date DATE DEFAULT '2005-01-01'
)
RETURNS INTEGER AS $$
DECLARE
rental_duration integer;
BEGIN
-- get the rental duration based on customer_id and rental date
SELECT INTO rental_duration
SUM( EXTRACT( DAY FROM return_date + '12:00:00' - rental_date))
FROM rental
WHERE customer_id= p_customer_id AND
rental_date >= p_from_date;
RETURN rental_duration;
END; $$
LANGUAGE plpgsql;
CREATE FUNCTION
This means that if we ignore passing p_from_date Parameters ,PostgreSQL Will use 2015 year 1 month 1 Day as default .
test=# SELECT get_rental_duration(232);
error : function get_rental_duration(integer) It's not the only one
LINE 1: SELECT get_rental_duration(232)
^
HINT: Unable to select the best candidate function . You may need to add explicit type conversions .
PostgreSQL Should I call the first function with one argument or the second function with two arguments ? It cannot choose . therefore , When reloading existing functions , Their functional interfaces should always be different . Now? , You can use only the second function by explicitly passing the second argument . The first function... Cannot be used , Because it makes PostgreSQL Confused which function to call .
We need to delete the with default values get_rental_duration() function , And recreate... Again with two parameters get_rental_duration function , There is no need to specify a default value for the second parameter .
test=# DROP FUNCTION get_rental_duration(INTEGER,DATE);
DROP FUNCTION
Please note that , When deleting a function , Both parameter and function names must be specified . actually , stay PostgreSQL in , The full name of the function includes the name and parameters .
The last important note is , Excessive heavy loads should be avoided , This makes it difficult for developers to look at the code to know which function to call .
Use ILIKE Operator returns all movies whose titles match a particular pattern
test=# CREATE OR REPLACE FUNCTION get_film (p_pattern VARCHAR)
RETURNS TABLE (
film_title VARCHAR,
film_release_year INT
)
AS $$
BEGIN
RETURN QUERY SELECT
title,
cast( release_year as integer)
FROM
film
WHERE
title ILIKE p_pattern ;
END; $$
LANGUAGE 'plpgsql';
CREATE FUNCTION
get_film(varchar) Function takes an argument p_pattern, This is the pattern you want to match with the movie title . To return a table from a function , Please use RETURNS TABLE Syntax and specify the columns of the table . Each column is marked with a comma (,) Separate .
In this function , We return a query , The query is SELECT Result of statement . Please note that ,SELECT The columns in the statement must match the columns of the table we want to return . Because of the data type of the movie table release_year Is not an integer , So we have to cast it to an integer using a cast .
call get_film(varchar) Function to get the title with Al All the movies at the beginning :
test=# SELECT
*
FROM
get_film ('Al%');
film_title | film_release_year
------------------+-------------------
Alabama Devil | 2006
Aladdin Calendar | 2006
Alamo Videotape | 2006
Alaska Phantom | 2006
Ali Forever | 2006
Alice Fantasia | 2006
Alien Center | 2006
Alley Evolution | 2006
Alone Trip | 2006
Alter Victory | 2006
(10 rows)
If you call this function with the following statement ,PostgreSQL Return a table with one column , It contains an array of movies :
test=# SELECT
get_film ('Al%');
get_film
---------------------------
("Alabama Devil",2006)
("Aladdin Calendar",2006)
("Alamo Videotape",2006)
("Alaska Phantom",2006)
("Ali Forever",2006)
("Alice Fantasia",2006)
("Alien Center",2006)
("Alley Evolution",2006)
("Alone Trip",2006)
("Alter Victory",2006)
(10 rows)
actually , Each row is usually processed before it is added to the result set of a function .
test=# CREATE OR REPLACE FUNCTION get_film (p_pattern VARCHAR,p_year INT)
RETURNS TABLE (
film_title VARCHAR,
film_release_year INT
) AS $$
DECLARE
var_r record;
BEGIN
FOR var_r IN(SELECT
title,
release_year
FROM film
WHERE title ILIKE p_pattern AND
release_year = p_year)
LOOP
film_title := upper(var_r.title) ;
film_release_year := var_r.release_year;
RETURN NEXT;
END LOOP;
END; $$
LANGUAGE 'plpgsql';
CREATE FUNCTION
Created a file with a similar name get_film(varchar,int) Function of , But accept two parameters :
The first parameter is p_pattern, If the title matches this pattern , We will use p_pattern Search for movies . We use ILIKE Operator to perform a search .
The second parameter is the year the movie was released .
Because each row needs to be processed before it is returned , So we use FOR LOOP Statement to process it . In each iteration , We use UPPER Function to capitalize the title of the movie .
RETURN NEXT Statement to add a row to the result set of the function . Carry on , And establish the result set in each iteration of the loop .
test=# SELECT
*
FROM
get_film ('wr%', 2006);
film_title | film_release_year
----------------+-------------------
WRATH MILE | 2006
WRONG BEHAVIOR | 2006
(2 rows)
9.PL/pgSQL IF sentence
IF Statement is used to conditionally execute a command .PL/pgSQL Provides you with three forms of IF sentence .
9.1、IF The simplest form of a statement
If the condition is true , be IF Statement execute statement . If the result of the condition is false, Pass control to END IF The next statement after the section . This is explained below IF The simplest form of a statement :
IF condition THEN
statement;
END IF;
The condition is a Boolean expression , The result is true or false.
This statement is the statement that will be executed when the condition is true . It can be any valid statement , It can even be another IF sentence .IF The code statement is placed in another IF Statement within , It's called nesting IF sentence .
test=# DO $$
DECLARE
a integer := 10;
b integer := 20;
BEGIN
IF a > b THEN
RAISE NOTICE 'a is greater than b';
END IF;
IF a < b THEN
RAISE NOTICE 'a is less than b';
END IF;
IF a = b THEN
RAISE NOTICE 'a is equal to b';
END IF;
END $$;
Be careful : a is less than b
DO
In this example , We declared two variables a and b. In the body of the block , We use IF The comparison operator in the Boolean expression of the statement >,< and = Compare a and b Value , And print out the corresponding message .
9.2、IF THEN ELSE sentence
9.2.1、IF THEN ELSE Sentence syntax
IF THEN ELSE Statement under condition true To execute an order , Condition is false Execute alternate command when . This is explained below IF THEN ELSE Sentence syntax :
IF condition THEN
statements;
ELSE
alternative-statements;
END IF;
9.2.1、IF THEN ELSE Statement example
test=# DO $$
DECLARE
a integer := 10;
b integer := 20;
BEGIN
IF a > b THEN
RAISE NOTICE 'a is greater than b';
ELSE
RAISE NOTICE 'a is not greater than b';
END IF;
END $$;
Be careful : a is not greater than b
DO
Because of the expression a > b For false , Therefore, the ELSE Statement in clause .
9.3、IF THEN ELSIF THEN ELSE sentence
9.3.1、IF THEN ELSIF THEN ELSE Sentence syntax
IF and IF THEN ELSE Statement allows you to evaluate only one condition . however , Use this form of IF sentence , You may need to evaluate several conditions .
IF condition-1 THEN
if-statement;
ELSIF condition-2 THEN
elsif-statement-2
...
ELSIF condition-n THEN
elsif-statement-n;
ELSE
else-statement;
END IF:
Condition is true, Then execute the corresponding statement in the branch . for example , If condition-1,condition-2 Wait for true, The corresponding statement will be executed :if-statement,elseif-statement-2 etc. . If a condition is met ,PostgreSQL The evaluation of the following conditions will be stopped .
If all the conditions are false, Then execute the last ELSE Statements in branches .
9.3.2、IF THEN ELSIF THEN ELSE Example
test=# DO $$
DECLARE
a integer := 10;
b integer := 10;
BEGIN
IF a > b THEN
RAISE NOTICE 'a is greater than b';
ELSIF a < b THEN
RAISE NOTICE 'a is less than b';
ELSE
RAISE NOTICE 'a is equal to b';
END IF;
END $$;
Be careful : a is equal to b
DO
In this example , because a be equal to b, So will execute ELSE Statements in branches .
10.PL/pgSQL CASE sentence
except IF Out of statement ,PostgreSQL It also provides CASE Statements that allow conditional execution of code blocks . The CASE There are two forms of statements : Simple CASE Statement and search CASE sentence .
10.1、 ordinary CASE sentence
CASE search-expression
WHEN expression_1 [, expression_2, ...] THEN
when-statements
[ ... ]
[ELSE
else-statements ]
END CASE;
search-expression It's an expression , It will use equal operands (=) With each WHEN Expression evaluation in branch . If I find a match , Then execute the corresponding WHEN In the branch when sentence . The following subsequent expressions will not be evaluated .
If no match is found , execute ELSE In the branch else sentence .ELSE Branches are optional . If no match is found , And there's no ELSE Branch , be PostgreSQL Will lead to CASE_NOT_FOUND abnormal .
10.2、 Simple CASE Examples of statements
test=# CREATE OR REPLACE FUNCTION get_price_segment(p_film_id integer)
RETURNS VARCHAR(50) AS $$
DECLARE
rate NUMERIC;
price_segment VARCHAR(50);
BEGIN
-- get the rate based on film_id
SELECT INTO rate rental_rate
FROM film
WHERE film_id = p_film_id;
CASE rate
WHEN 0.99 THEN
price_segment = 'Mass';
WHEN 2.99 THEN
price_segment = 'Mainstream';
WHEN 4.99 THEN
price_segment = 'High End';
ELSE
price_segment = 'Unspecified';
END CASE;
RETURN price_segment;
END; $$
LANGUAGE plpgsql;
CREATE FUNCTION
test=# SELECT get_price_segment(123) AS "Price Segment";
Price Segment
---------------
High End
(1 row)
In this example , We created a get_price_segment The new function of , This function accepts p_film_id As a parameter . According to the movie rent , It returns the price segment : The public , Main stream , High-end . If the price is not 0.99、2.99 or 4.99, Then the function returns the unspecified price .
10.3、 The search of CASE sentence
The following syntax describes the CASE sentence
CASE
WHEN boolean-expression-1 THEN
statements
[ WHEN boolean-expression-2 THEN
statements
... ]
[ ELSE
statements ]
END CASE;
The search of CASE Statements are based on each WHEN Clause to execute the statement .PostgreSQL Evaluate Boolean expressions from top to bottom , Until an expression is true . Then evaluate the stop and execute the corresponding statement . Control in END CASE Then pass to the next statement .
If you can't find the right result , execute ELSE Statement in clause .ELSE Clauses are optional . If omitted ELSE Clause , But no real results , be PostgreSQL Will lead to CASE_NOT_FOUND abnormal .
10.4、 The search of CASE Statement example
test=# CREATE OR REPLACE FUNCTION get_customer_service (p_customer_id INTEGER)
RETURNS VARCHAR (25) AS $$
DECLARE
total_payment NUMERIC ;
service_level VARCHAR (25) ;
BEGIN
-- get the rate based on film_id
SELECT
INTO total_payment SUM (amount)
FROM
payment
WHERE
customer_id = p_customer_id ;
CASE
WHEN total_payment > 200 THEN
service_level = 'Platinum' ;
WHEN total_payment > 100 THEN
service_level = 'Gold' ;
ELSE
service_level = 'Silver' ;
END CASE ;
RETURN service_level ;
END ; $$
LANGUAGE plpgsql;
CREATE FUNCTION
get_customer_service Function acceptance p_customer_id As a parameter . It first obtains the total payment paid by the customer from the payment table . then , Based on total payment , This function uses the CASE Statement returns the service level platinum , Gold and silver .
test=# SELECT
148 AS customer,
get_customer_service (148)
UNION
SELECT
178 AS customer,
get_customer_service (178)
UNION
SELECT
81 AS customer,
get_customer_service (81);
customer | get_customer_service
----------+----------------------
178 | Gold
81 | Silver
148 | Platinum
(3 rows)
Please note that , To search the case Statement similar to IF ELSIF ELSE sentence .
11.PL/pgSQL Loop statement
PostgreSQL Three loop statements are provided :LOOP,WHILE Circulation and FOR loop .
11.1、LOOP sentence
11.1.1、LOOP Sentence syntax
Sometimes , You need to repeat a statement block , Until the condition becomes true . So , have access to PL/pgSQL LOOP sentence . This is explained below LOOP Sentence syntax :
<<label>>
LOOP
Statements;
EXIT [<<label>>] WHEN condition;
END LOOP;
LOOP Statements are also called unconditional loop statements , Because it executes the statement until EXIT The condition in the statement evaluates to true. Please note that , stay EXIT Statement WHEN The condition specified after the keyword is a Boolean expression , The result is true or false.
Loop statements can be nested . One LOOP Statement placed in another LOOP In the sentence , This is called a nested loop . under these circumstances , You need to specify for the loop label that you want to EXIT Loop terminated in statement .
11.1.2、PL/pgSQL LOOP Example
Use LOOP Statement development returns to the n A function of Fibonacci serial number .
test=# CREATE OR REPLACE FUNCTION fibonacci (n INTEGER)
RETURNS INTEGER AS $$
DECLARE
counter INTEGER := 0 ;
i INTEGER := 0 ;
j INTEGER := 1 ;
BEGIN
IF (n < 1) THEN
RETURN 0 ;
END IF;
LOOP
EXIT WHEN counter = n ;
counter := counter + 1 ;
SELECT j, i + j INTO i, j ;
END LOOP ;
RETURN i ;
END ;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
Fibonacci The() function accepts an integer and returns the n Fibonacci Numbers . According to the definition , Fibonacci number is expressed in 0 and 1 A sequence of integers starting with , Each subsequent number is the sum of the first two numbers , for example 1、1、2(1 + 1),3(2 + 1), 5(3 +2),8(5 + 3),......
In the declaration section , Initialize the counter variable to zero (0). Inside the loop , When the counter is equal to n when , Loop exit .
SELECT j, i + j INTO i, j ;
Without using temporary variables , Exchange at the same time i and j.
11.2、WHILE loop
WHILE A loop statement executes a block of statements , Until the condition is evaluated as false. stay WHILE In loop statement ,PostgreSQL Evaluate the condition before executing the statement block . If the condition is true, Then execute the statement block , Until the assessment is false.
11.2.1、WHILE Cyclic grammar
[ <<label>> ]
WHILE condition LOOP
statements;
END LOOP;
11.2.2、WHILE Loop example
Use loop Statement rewriting Fibonacci function , As shown below :
test=# CREATE OR REPLACE FUNCTION fibonacci (n INTEGER)
RETURNS INTEGER AS $$
DECLARE
counter INTEGER := 0 ;
i INTEGER := 0 ;
j INTEGER := 1 ;
BEGIN
IF (n < 1) THEN
RETURN 0 ;
END IF;
WHILE counter <= n LOOP
counter := counter + 1 ;
SELECT j, i + j INTO i, j ;
END LOOP ;
RETURN i ;
END ;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
11.3、FOR Loop statement
FOR The loop statement is PostgreSQL The most complex loop statement in .
11.3.1、 Used to traverse the integer range
FOR Loop through the range of integers loop Sentence syntax :
[ <<label>> ]
FOR loop_counter IN [ REVERSE ] from.. to [ BY expression ] LOOP
statements
END LOOP [ label ];
First ,PostgreSQL Create an integer variable that exists only inside the loop loop_counter. By default , The loop counter is added after each iteration . If you use REVERSE keyword ,PostgreSQL The cycle counter will be subtracted .
secondly ,from and to Is an expression that specifies the lower and upper limits of the range .PostgreSQL These expressions are evaluated before entering the loop .
Third ,BY Clause specifies the iteration step . If you omit this option , The default step is 1.PostgreSQL The expression is also evaluated once in the loop entry .
11.3.2、FOR Examples of loop statements 1
Loop traversal 1 To 5, And print out a message in each iteration . The counter needs 1、2、3、4、5. In each iteration of the loop ,PostgreSQL take 1 Add to the counter .
DO $$
BEGIN
FOR counter IN 1..5 LOOP
RAISE NOTICE 'Counter: %', counter;
END LOOP;
END; $$
11.3.3、FOR Examples of loop statements 2
from 5 Loop to 1, And print a message in each iteration . The counter takes 5、4、3、2、1. In each iteration ,PostgreSQL Subtract... From the counter 1.
DO $$
BEGIN
FOR counter IN REVERSE 5..1 LOOP
RAISE NOTICE 'Counter: %', counter;
END LOOP;
END; $$
11.3.4、FOR Examples of loop statements 3
stay 1 To 6 In between , And print out the counter in each cycle iteration . The counter takes 1、3、5. In each iteration ,PostgreSQL take 2 Add to the counter .
DO $$
BEGIN
FOR counter IN 1..6 BY 2 LOOP
RAISE NOTICE 'Counter: %', counter;
END LOOP;
END; $$
11.4、FOR Loop through the query results
11.4.1、 Syntax for traversing query results
[ <<label>> ]
FOR target IN query LOOP
statements
END LOOP [ label ];
11.4.2、 Example of traversing query results
The following function accepts an integer , This integer specifies the... To be retrieved from the sample database film Number of rows queried in the table .FOR Loop statement loop through the rows returned by the query , And print out the movie title .
test=# CREATE OR REPLACE FUNCTION for_loop_through_query(
n INTEGER DEFAULT 10
)
RETURNS VOID AS $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT title
FROM film
ORDER BY title
LIMIT n
LOOP
RAISE NOTICE '%', rec.title;
END LOOP;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
test=# SELECT for_loop_through_query(5);
for_loop_through_query
------------------------
(1 row)
Be careful : Academy Dinosaur
Be careful : Ace Goldfinger
Be careful : Adaptation Holes
Be careful : Affair Prejudice
Be careful : African Egg
11.5、 Query results for traversing dynamic queries
11.5.1、 Traverse the syntax of dynamic queries
Sometimes , You want to be in PL/pgSQL Function to construct a dynamic query and traverse its results . So , have access to FOR The syntax of circular statements :
[ <<label>> ]
FOR row IN EXECUTE string_expression [ USING query_param [, ... ] ]
LOOP
statements
END LOOP [ label ];
You can use string expressions ( It's text formatted SQL sentence ) Instead of SQL sentence . This allows you to dynamically construct queries .
If the query has parameters , You can use USING Statement to pass parameters to a query .
11.5.2、 Traversal dynamic query example
The following function demonstrates how to use FOR Loop statements loop through dynamic queries . It takes two arguments :
sort_type:1 Indicates sorting query results by title ,2 Indicates sorting results by release year .
n: Number of rows to query from the movie table . Be careful , It will be USING Used in clauses .
First , We build the query based on the input parameters , And then in FOR Execute query in loop function .
test=# CREATE OR REPLACE FUNCTION for_loop_through_dyn_query(
sort_type INTEGER,
n INTEGER
)
RETURNS VOID AS $$
DECLARE
rec RECORD;
query text;
BEGIN
query := 'SELECT title, release_year FROM film ';
IF sort_type = 1 THEN
query := query || 'ORDER BY title';
ELSIF sort_type = 2 THEN
query := query || 'ORDER BY release_year';
ELSE
RAISE EXCEPTION 'Invalid sort type %s', sort_type;
END IF;
query := query || ' LIMIT $1';
FOR rec IN EXECUTE query USING n
LOOP
RAISE NOTICE '% - %', rec.release_year, rec.title;
END LOOP;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
call for_loop_through_dyn_query() obtain 5 Film and sort by title :
test=# SELECT for_loop_through_dyn_query(1,5);
for_loop_through_dyn_query
----------------------------
(1 row)
Be careful : 2006 - Academy Dinosaur
Be careful : 2006 - Ace Goldfinger
Be careful : 2006 - Adaptation Holes
Be careful : 2006 - Affair Prejudice
Be careful : 2006 - African Egg
call for_loop_through_dyn_query() obtain 5 Films and sorted by release year :
test=# SELECT for_loop_through_dyn_query(2,5);
for_loop_through_dyn_query
----------------------------
(1 row)
Be careful : 2006 - Grosse Wonderful
Be careful : 2006 - Airport Pollock
Be careful : 2006 - Bright Encounters
Be careful : 2006 - Academy Dinosaur
Be careful : 2006 - Chamber Italian
12.PL/pgSQL The cursor
PL/pgSQL Cursors allow us to encapsulate queries and process each individual row at once . When we want to divide a large result set into multiple parts and deal with each part separately , We use cursors . If we deal with it immediately , Memory overflow errors may occur .
in addition , We can develop a function that returns a reference to a cursor . This is an effective way to return a large result set from a function . Function callers can process result sets based on cursor references .
To use a cursor :
First , Declare a cursor .
Next , Open the cursor .
then , Extract the rows in the result set into the target .
after , Check if there are any remaining rows to extract . yes , Execution steps 3, Otherwise, carry out the steps 5.
Last , Close the cursor .
12.1、 declare cursor
To access the cursor , A cursor variable needs to be declared in the declaration part of the block .PostgreSQL It provides us with a kind of product called REFCURSOR To declare cursor variables :
DECLARE
my_cursor REFCURSOR;
Another way to declare a cursor bound to a query is to use the following syntax :
cursor_name [ [NO] SCROLL ] CURSOR [( name datatype, name data type, ...)] FOR query;
First , Specify a variable name for the cursor .
Next , Specify whether you can use SCROLL Scroll the cursor backwards . If you use NO SCROLL, You cannot scroll the cursor backwards .
then , place CURSOR keyword , Followed by a comma separated list of parameters ( Name data type ), These parameters define the parameters of the query . When opening cursor , These parameters will be replaced by values .
after , Can be in FOR Keyword followed by a query . Any valid... Can be used here SELECT sentence .
Declare cursor examples
DECLARE
cur_films CURSOR FOR SELECT * FROM film;
cur_films2 CURSOR (year integer) FOR SELECT * FROM film WHERE release_year = year;
cur_films It's a cursor , It encapsulates the film All the rows in the table .
cur_films2 It's a cursor , Used to package movies with a specific release year in film In the table .
12.2、 Open cursor
The cursor must be opened before it can be used to query rows .PostgreSQL Provides syntax for opening unbound and bound cursors .
12.2.1、 Open unbound cursor
Use the following syntax to open an unbound cursor :
OPEN unbound_cursor_variable [ [ NO ] SCROLL ] FOR query;
Because the unbound cursor variable at the time of declaration is not bound to any query , So you must specify a query when you open it :
OPEN my_cursor FOR SELECT * FROM city WHERE counter = p_country;
PostgreSQL Allows us to open a cursor and bind it to a dynamic query . The grammar is as follows :
OPEN unbound_cursor_variable[ [ NO ] SCROLL ]
FOR EXECUTE query_string [USING expression [, ... ] ];
In the following example , We built a dynamic query , The query is based on sort_field Parameter to sort rows , And open the cursor that executes the dynamic query :
query := 'SELECT * FROM city ORDER BY $1';
OPEN cur_city FOR EXECUTE query USING sort_field;
12.2.2、 Open bound cursor
Because the cursor bound at the time of declaration is already bound to the query , So when we open it , Just pass the parameters to the query if necessary :
OPEN cursor_variable[ (name:=value,name:=value,...)];
In the following example , We opened the binding cursor declared above cur_films and cur_films2:
OPEN cur_films;
OPEN cur_films2(year:=2005);
12.2.3、 Use cursors
After opening the cursor , We can use FETCH,MOVE,UPDATE or DELETE Statement to operate on it .
12.3、 Get the next line
FETCH [ direction { FROM | IN } ] cursor_variable INTO target_variable;
FETCH Statement to get the next line from the cursor , And assign a target_variable, The target_variable It can be a record , Row variables or comma separated list of variables . If no more rows are found , Will target_variable Set to NULL.
By default , If you do not specify a direction , The cursor will move to the next line . The following is valid for cursors :
NEXT
LAST
PRIOR
FIRST
ABSOLUTE count
RELATIVE count
FORWARD
BACKWARD
Please note that ,FORWARD and BACKWARD The direction is only applicable to the use of SCROLL Option declared cursors .
Get an example of a cursor :
FETCH cur_films INTO row_film;
FETCH LAST FROM row_film INTO title, release_year;
12.4、 Move the cursor
MOVE [ direction { FROM | IN } ] cursor_variable;
If you just want to move the cursor without retrieving any rows , You can use MOVE sentence . This direction accepts and FETCH Statement with the same value .
MOVE cur_films2;
MOVE LAST FROM cur_films;
MOVE RELATIVE -1 FROM cur_films;
MOVE FORWARD 3 FROM cur_films;
12.5、 Delete or update rows
After positioning the cursor , have access to DELETE WHERE CURRENT OF or UPDATE WHERE CURRENT OF Statement to delete or update the row identified by the cursor , As shown below :
UPDATE table_name
SET column = value, ...
WHERE CURRENT OF cursor_variable;
DELETE FROM table_name
WHERE CURRENT OF cursor_variable;
See the following example :
UPDATE film SET release_year = p_year
WHERE CURRENT OF cur_films;
To close an open cursor , Use CLOSE sentence , As shown below :
CLOSE cursor_variable;
CLOSE Statement to release resources , Or the cursor variable is released , Make it reusable OPEN Statement open .
12.6、PL/pgSQL The cursor – All put together
following get_film_titles(integer) The function accepts a parameter that indicates the year the movie was released . Inside the function , Query all movies whose release year is equal to the release year passed to this function . Use the cursor to cycle through the rows , And link the title to the year the movie was released , The title of the movie contains ful .
test=# CREATE OR REPLACE FUNCTION get_film_titles(p_year INTEGER)
RETURNS text AS $$
DECLARE
titles TEXT DEFAULT '';
rec_film RECORD;
cur_films CURSOR(p_year INTEGER)
FOR SELECT title, release_year
FROM film
WHERE release_year = p_year;
BEGIN
-- Open the cursor
OPEN cur_films(p_year);
LOOP
-- fetch row into the film
FETCH cur_films INTO rec_film;
-- exit when no more row to fetch
EXIT WHEN NOT FOUND;
-- build the output
IF rec_film.title LIKE '%ful%' THEN
titles := titles || ',' || rec_film.title || ':' || rec_film.release_year;
END IF;
END LOOP;
-- Close the cursor
CLOSE cur_films;
RETURN titles;
END; $$
LANGUAGE plpgsql;
CREATE FUNCTION
test=# SELECT get_film_titles(2006);
get_film_titles
----------------------------------------------------------------------------------------------------------
,Grosse Wonderful:2006,Day Unfaithful:2006,Reap Unfaithful:2006,Unfaithful Kill:2006,Wonderful Drop:2006
(1 row)
13.PostgreSQL The creation process
13.1、CREATE PROCEDURE Sentence syntax
To create a new stored procedure , Please use CREATE PROCEDURE sentence . The following shows CREATE PROCEDURE A simplified syntax for statements :
CREATE [OR REPLACE] PROCEDURE procedure_name(parameter_list)
LANGUAGE language_name
AS $$
stored_procedure_body;
$$;
First , stay CREATE PROCEDURE Clause to specify the name of the stored procedure .
Next , Define a parameter list similar to the parameter list of user-defined functions .
then , Specify the programming language for the stored procedure , for example PLpgSQL and SQL.
after , Place the code in the body of the stored procedure AS After keyword .
Last , Use binary ($$) End stored procedure .
Different from user-defined functions , The stored procedure did not return a value . If you want to end the process earlier , You can use... Without any expression RETURN sentence , As shown below :
RETURN;
If you want to return a value from a stored procedure , You can use the output parameter . The final value of the output parameter is returned to the caller .
13.2、 Create a sample stored procedure
Use the following accounts Table :
test=# CREATE TABLE accounts (
id INT GENERATED BY DEFAULT AS IDENTITY,
name VARCHAR(100) NOT NULL,
balance DEC(15,2) NOT NULL,
PRIMARY KEY(id)
);
INSERT INTO accounts(name,balance)
VALUES('Bob',10000);
INSERT INTO accounts(name,balance)
VALUES('Alice',10000);
CREATE TABLE
INSERT 0 1
INSERT 0 1
Here are accounts Table data :
test=# SELECT * FROM accounts;
id | name | balance
----+-------+----------
1 | Bob | 10000.00
2 | Alice | 10000.00
(2 rows)
Create a file called transfer Stored procedure , This process transfers the specified amount from one account to another :
test=# CREATE OR REPLACE PROCEDURE transfer(INT, INT, DEC)
LANGUAGE plpgsql
AS $$
BEGIN
-- subtracting the amount from the sender's account
UPDATE accounts
SET balance = balance - $3
WHERE id = $1;
-- adding the amount to the receiver's account
UPDATE accounts
SET balance = balance + $3
WHERE id = $2;
COMMIT;
END;
$$;
CREATE PROCEDURE
To call a stored procedure , Please use CALL sentence , As shown below :
CALL stored_procedure_name(parameter_list);
Call the stored procedure and verify :
test=# CALL transfer(1,2,1000);
CALL
test=# SELECT * FROM accounts;
id | name | balance
----+-------+----------
1 | Bob | 9000.00
2 | Alice | 11000.00
(2 rows)
边栏推荐
- Teach you to use elastic search: run the first hello world search command
- 新产品新人事新服务,英菲尼迪继续深耕中国未来可期!
- VSCode 建议你启用 gopls,它到底是个什么东东?
- WOx WPM installing the Youdao plug-in
- SQL update批量更新
- 国产数据库认证考试指南汇总(2022年6月16日更新)
- How to rewrite tdengine code from 0 to 1 with vscode in "technical class"
- Redis系列2:数据持久化提高可用性
- After the number length of Oracle exceeds 19, the entity uses long mapping. Why does this cause problems?
- 推荐几个开源的物联网平台
猜你喜欢
WOx WPM installing the Youdao plug-in
Redis installation
Recommend several open source IOT platforms
Wanzhou gold industry: a common technical term in gold t+d transaction?
VSCode 建议你启用 gopls,它到底是个什么东东?
Shardingsphere & Atlas & MYCAT comparison
PostgreSQL数据库WAL——资源管理器RMGR
Asemi rectifier bridge kbp210 parameters, kbp210 specifications, kbp210 dimensions
【网络研讨会】MongoDB 携手 Google Cloud 加速企业数字化创新
Mise à jour SQL mise à jour par lots
随机推荐
How much room does Migu video have for development without relying on sports events?
Explain the distributed computing of Apache skywalking OAP in detail
R language statistics a program running time function system time
The data synchronization tool dataX has officially supported reading and writing tdengine
数据同步工具 DataX 已经正式支持读写 TDengine
Hikvision Tools Manager海康威视工具大全(含SADP、录像容量计算等工具)百万安防从业者的实用工具
TP5 restrict access frequency
【网络研讨会】MongoDB 携手 Google Cloud 加速企业数字化创新
Market status and development prospect forecast of global triisopropyl chlorosilane industry in 2022
技术分享 | kubernetes pod 简介
Software testing Basics - software testing history, process, classification, benefits, limitations
开源之夏 2022 | openGauss 项目中选公布
Offline disk group
Seata server database connection user and service database undo_ What permissions do log users need?
DOM object in JS
Asemi rectifier bridge kbp307 parameters, kbp307 details, kbp307 pictures
Explain in detail the differences between opentsdb and tdengine in system functions
MFS distributed file system
Contest3182 - the 39th individual training match for 2021 freshmen_ C: [string] ISBN number
The power of code refactoring: how to measure the success of refactoring