All knowledge system articles,GitHubWelcome Star! Thank you again and wish you a speedy entry into Dachang!
GitHub address: github.com/Ziphtracks/…
MySQL stored procedure
1. Stored procedures
1.1 What is a Stored Procedure
In a large database system, Stored Procedure is a set of SQL statements to complete a specific function. It is Stored in the database and lasts forever after compilation. Users can execute it by specifying the name of the Stored Procedure and giving parameters (if the Stored Procedure has parameters). A stored procedure is an important object in a database. The efficiency can be improved twice as fast by using stored procedures when the data volume is very large
1.2 Database stored procedure program
Once we understand what a stored procedure is, we need to understand the three types of database storage type programs that exist in the database, as follows:
- Stored procedure: A stored procedure is the most common type of stored program. A stored procedure is a unit of program that can accept input and output parameters and be executed on request.
- Stored functions: Stored functions are similar to stored procedures, but the result of their execution returns a value. Most importantly, storage functions can be used to act as standard SQL statements, allowing programmers to effectively extend the capabilities of the SQL language.
- Triggers: Triggers are stored programs that respond to events that activate or trigger database behavior. Typically, triggers are invoked as responses to database manipulation languages, and triggers can be used as data checksums to automatically reverse format.
Note: Other databases provide additional data stores, including packages and classes. Currently MySQL does not provide this structure.
1.3 Why use a stored program
Although we don’t use a lot of stored programs in current development, we don’t have to deny it. In fact, stored programs give us many advantages in using and managing databases:
- Using stored programs is more secure.
- Stored programs provide an abstraction mechanism for data access that can greatly improve the maintainability of your code as the underlying data structure evolves.
- Stored applications can reduce network congestion because the data belongs to the database server internally, which is much faster than transferring data over the network.
- Stored programs can implement shared access routines for multiple peripheral applications that use different architectures, whether based outside or inside the database server.
- Data-centric logic can be placed independently in stored programs, giving programmers a higher, more unique database programming experience.
- In some cases, using stored programs can improve application portability. (In other cases, portability can be poor!)
Here I’ll briefly explain some of the advantages of using stored programs:
Remember that in the Java language, we use databases and Java code to combine persistent storage with JDBC. When WE think of JDBC, can we also think of SQL injection issues? Is it really completely safe to use preparedStatements for SQL injection problems? No, it’s not perfectly safe.
At this time analyze the database and Java code connection operation process. In THE BS structure, the browser generally visits the server, and then the server sends SQL statements to the database. The SQL statements are compiled and run in the database, and finally the results are processed by the server and returned to the browser. In this operation process, the browser to the server every time to send a database operation request will call the corresponding SQL statement compilation and execution, this is a very waste of performance, performance decline means that the operation efficiency of the database is low.
Another possibility is that the SQL statement that is transmitted in this process is the SQL statement that operates on the real library table. If it is intercepted in the process of transmission, some criminals will infer the structure of the library table in our database according to the SQL statement that is intercepted, which is a great security risk.
Here’s a scenario for improving maintainability. A database is typically managed by a DBA in a company. If the DBA who managed the database for many years resigns, the database is managed by the next DBA. The problem here is that the amount of data and SQL statements in the database is obviously not very friendly to the next manager. Even dbAs who have managed the database for years can forget something if they don’t check the database for too long. Therefore, we need to introduce stored procedures for the unified compilation and compilation of SQL statements, to provide convenience for maintenance. (Actually, I think this example is not vivid and reasonable, but for everyone to understand, please understand!)
Explained a lot of stored program advantage evolution process, its core is: need to compile one or more SQL statements placed in the database side of the storage program, in order to solve the above problems and convenient for developers to call directly.
2. Procedures for using stored procedures
2.1 Development idea of stored procedure
A stored procedure is an important object of a database. It can encapsulate SQL statement sets, and can be used to complete some complex business logic. It can also input parameters (pass parameters) and output parameters (return parameters), which is very similar to the encapsulation in Java.
And the creation of pre-compiled and saved, the developer subsequent calls do not need to compile again.
2.2 Advantages and disadvantages of stored procedures
The advantages and disadvantages of using stored procedures are actually covered in advantage 1.3. Here I will briefly outline the advantages and disadvantages of stored procedures.
- Advantages:
- In a production environment, you can modify business logic or bugs directly by modifying stored procedures without restarting the server.
- Fast execution. Stored procedures are compiled much faster than compiled and executed separately.
- Reduce network traffic.
- Easy for developers or DBAs to use and maintain.
- Improved portability with the same database syntax.
- Disadvantages:
- Procedural programming and high maintenance cost of complex business processing.
- Inconvenient debugging.
- Because the syntax of different databases is inconsistent, portability between different databases is poor.
2.3 official documentation of MySQL stored Procedures
Good English or capable partners can refer to the official documents. If you don’t refer to the official documentation, don’t worry, I will also cover the details of MySQL stored procedures below.
https:/ / dev.mysql.com/doc/refman/5.6/en/preface.html
Copy the code
2.3 Usage syntax of stored Procedures
create PROCEDUREProcess name (in|out| inout parameter data types,...).begin
sqlStatements;end;
callProcedure name (parameter value);Copy the code
In is the keyword that defines the parameters passed in. Out is the keyword that defines the parameter. Inout is a parameter that defines both inbound and outbound parameters. If nothing is defined in parentheses, the stored procedure is a function with no arguments. Detailed case studies will follow.
Note: The default terminator for SQL statements is; When using the above stored procedure, a syntax error of 1064 is reported. We can temporarily change the end of the SQL statement to // using the DELIMITER keyword, as follows:
-- Temporarily define terminator as "//"
DELIMITER //
create PROCEDUREProcess name (in|outParameter name Data type...begin
sqlStatements;end//
-- Redefines the terminator back to ";"
DELIMITER ;
Copy the code
Example: Use a stored procedure to query an employee’s salary (no parameter)
Note: We can also use the delimiter keyword to delimit; In the following case I did not declare the terminator back to the original; Please pay attention to this
Why do I provide drop here?
If we need to modify the contents of the stored procedure, we need to delete the existing stored procedure before creAT is created again.
Create PROCEDURE se() begin Select SALARY from employee; Drop procedure if exists se //Copy the code
Variables and assignments of stored procedures
3.1 Local variables
Declare var_name type [default var_value];
Assignment syntax:
Note: The definition of local variables is valid in begin/end blocks.
Assign values to parameters using set
Create PROCEDURE VAL_set () BEGIN # Declare a val_name local variable with a default value of unknown val_name varchar(32) default 'unknown'; Set val_name = 'Centi'; Select val_name; Call val_set() //Copy the code
Use into to receive parameters
Delimiter // create procedure VAL_INTO () BEGIN # Define two variables where name and age DECLARE val_name VARCHar (32) default 'unknown'; declare val_age int; Select name,age into val_name,val_age from employee where id = 1; select val_age from employee where id = 1; Select val_name,val_age; end // call val_into() //Copy the code
3.2 User Variables
User – defined user variable, valid for current session (connection). Similar to member variables in Java.
- Grammar:
@val_name
- Note: This user variable does not need to be declared in advance.
delimiter //
create procedure val_user()
beginAssign a value to a user variableset @val_name = 'Lacy';
end// # call the functioncallVal_user () // # query the user variableselect @val_name //
Copy the code
3.3 Session Variables
Session variables are provided by the system and are only valid in the current session (connection).
Grammar: @ @ session. Val_name
Show session variables; Select @@session.val_name; Set @@session.val_name = 0;Copy the code
Here I get all the session variables, about 500 session variable records. After we learn more about MySQL and understand the function of each session variable value, we can modify the session variable value according to requirements and scenarios.
delimiter //
create procedure val_session(a)Begin # Show session variables;
end //
call val_session(a) //
Copy the code
3.4 Global Variables
Global variables are provided by the system and are valid throughout the MySQL server.
Grammar: @ @ global val_name
Show global variables like '%char%' // # check the character_set_client value @@global.character_set_client //Copy the code
3.5 Input and output parameters
The syntax for input and output parameters was mentioned at the beginning of this article, but not demonstrated. Here I will demonstrate the use of input and output parameters.
Grammar: in | out | inout parameter data types,…
In defines parameters; Out defines the input parameter; Inout defines outbound and inbound parameters.
The participation in
When we use the in parameter, we need to pass in the parameter, and we can change the parameter here. Simply put, in is only responsible for passing parameters to stored procedures, similar to parameters in Java.
delimiter //
create procedure val_in(in val_name varchar(32))
begin# use user variables to assign parameter values to user variablesset @val_name1 = val_name;
end// # call the functioncall val_in('DK'// # query the user variableselect @val_name1 //
Copy the code
In and out
When using out, you pass in a parameter. This parameter is equivalent to the return value and can be called or received to retrieve the content of this parameter. Simply put, out is only the return value.
Delimiter create PROCEDURE val_OUT (in val_id int,out val_name vARCHar (32)) begin # Select name into val_name from employee where id = val_id; select name from employee where id = val_id; Call val_out(1, @n) select @n //Copy the code
Input parameter and output parameter inout
The inout keyword is used to combine in and out into one keyword. A parameter modified by a keyword can be either an input or an output parameter.
Delimiter // create PROCEDURE VAL_INout (in val_name vARCHar (32), inout val_age int) begin # Declare a variable A int; Set a = val_age; Select age into val_age from employee where name = val_name; Select concat(a, '-', val_age); Call val_inout('Ziph', @ages) // # execute result # 40-18Copy the code
4. Flow control in stored procedures
4.1 If Condition Judgment (recommended)
Extension: timestampdiff(unit, exp1, exp2) is the difference between exp2 and exp1, in units. (often used of dates)
Select timestampdiff(year, ‘2020-6-6’,now()) from emp e where id = 1;
Example: Query the age of employee 1 in the employee table, exp2 can be the date of the employee’s birth, and the unit is year.
Grammar:
IF conditional judgment THEN result [ELSEIF conditional judgment THEN result]... Results [ELSE]END IF
Copy the code
For example, enter the id parameter to query the salary standard (s<=6000 indicates the low salary standard; 6000< S <=10000 is the median wage standard; 10000< S <=15000 is the middle and upper wage standard; S >=15000 is the high salary standard)
Delimiter // create PROCEDURE s_sql(in val_id int) begin # Declare result VARCHar (32); Declare s double; declare s double; Select salary into s from employee where id = val_id; If s <= 6000 then set result = 'low '; Elseif s <= 10000 then set result = 10000; Elseif s <= 1000 then set result = '0 '; Else set result = 'high salary '; end if; # select result from salary; End // # call s_sql(1);Copy the code
4.2 Case Condition judgment
Case statements are not only used in stored procedures, but also in basic MySQL queries. This is equivalent to the Switch statement in Java.
Grammar:
CASE case_value WHEN when_value THEN result [WHEN when_value THEN result] [ELSE result] END CASE # 标 签 : END CASE [ELSE result] END CASE [ELSE result] END CASECopy the code
For example:
# delimiter // create PROCEDURE s_case(in val_id int) begin # Declare result VARCHar (32); Declare s double; declare s double; Select salary into s from employee where id = val_id; Case s when 6000 then set result = 'c '; When 10000 then set result = 'c '; Then set result = 'c '; Else set result = 'high salary '; end case; select result; end // call s_case(1); Delimiter // create PROCEDURE s_case(in val_id int) begin # Declare result VARCHar (32); Declare s double; declare s double; Select salary into s from employee where id = val_id; Case when s <= 6000 then set result = 'c '; When s <= 10000 then set result = 'c '; When s <= 1000 then set result = 'c '; Else set result = 'high salary '; end case; select result; end // call s_case(1);Copy the code
4.3 the loop cycle
Loop is an infinite loop and requires manual exit. We can use leave to exit the loop
You can think of leave as a Java break; As a counterpoint, iterate, also known as Java continue
Grammar:
[Alias :] LOOP StatementEND LOOP[alias]Copy the code
Note that aliases and aliases control the same tag.
Example 1: Loop print 1 to 10 (exit of leave control loop)
Note: the loop is an infinite loop, and the number from 1 to 10 is I. In the infinite loop, the loop is set to stop when the value is greater than or equal to 10, that is, the contents of the loop are executed 10 times, the result is queried 10 times, and 10 results are generated (1 to 10).
Delimiter // create procedure s_loop() begin # Declare counter DECLARE I int default 1; Num: loop num: loop If I >= 10 then leave num; end if; Set I = I + 1; End loop num; end // call s_loop();Copy the code
Print result:
Example 2: Loop print 1-10 (iterate and leave control loop)
Note: here we use string concatenation of counter results, as opposed to iterate, which must be I < 10!
Delimiter // create procedure s_loop1() begin # declare variable I counter declare I int default 1; # declare string container STR vARCHar (256) default '1'; Set I = I + 1; Set STR = concat(STR, '-', I); Iterate if I < 10 then iterate num; end if; If the counter I is greater than 10, leave num; End loop num; Select STR; end // call s_loop1();Copy the code
4.4 repeat loop
The repeat loop is similar to the Do while loop in Java, which does not end until the condition is not met.
Grammar:
[alias :] REPEAT loop statement UNTIL condition END REPEAT [alias]Copy the code
Example: Print 1 to 10 cycles
delimiter // create procedure s_repeat() begin declare i int default 1; declare str varchar(256) default '1'; Num: repeat set I = I + 1; set str = concat(str, '-', i); End repeat num until I >= 10 end repeat num; Select STR; end // call s_repeat();Copy the code
4.5 the while loop
The while loop is similar to the While loop in Java.
Grammar:
[alias] WHILE conditionDOLooping statementsEND WHILE[alias]Copy the code
Example: Print 1 to 10 cycles
delimiter // create procedure s_while() begin declare i int default 1; declare str varchar(256) default '1'; While I < 10 do set I = I + 1; set str = concat(str, '+', i); End while num; Select STR; end // call s_while();Copy the code
4.6 Flow Control Statements (Continue and End)
As for the continuation and termination of process control, we have already used this. Let me list them again.
Leave: with Java break; similar
Leave the tag;Copy the code
Iterate: As with Java continue; similar
Iterate tags;Copy the code
Cursor and handler
5.1 the cursor
Cursors are used to retrieve a result set and process the data line by line. The row by row operation of the cursor results in the cursor being rarely used!
Grammar:
DECLAREName of the cursorCURSOR FORThe query-- Open syntax
OPENName of the cursor-- Value syntax
FETCHName of the cursorINTO var_name [, var_name] ...
-- Turn off syntax
CLOSEName of the cursorCopy the code
Knowing the syntax of cursors, we started using cursors. As follows:
Example: Query ID, name, and SALARY using a cursor.
delimiter // create procedure f() begin declare val_id int; declare val_name varchar(32); declare val_salary double; # declare emp_flag cursor for SELECT ID, name, salary from employee; # open emp_flag; Fetch emp_flag into val_id, val_name, val_salary; # close emp_flag; select val_id, val_name, val_salary; end // call f();Copy the code
Execution Result:
Because of the row-by-row nature of cursors, we can only use cursors to query one row of records. How can the code be improved to query all records? The smart ones thought of using loops. Yeah, let’s try a loop.
delimiter // create procedure f() begin declare val_id int; declare val_name varchar(32); declare val_salary double; # declare emp_flag cursor for SELECT ID, name, salary from employee; # open emp_flag; C :loop # fetch emp_flag into val_id, val_name, val_salary; end loop; # close emp_flag; select val_id, val_name, val_salary; end // call f();Copy the code
After we use the loop, we find that there is a problem, because the loop is an infinite loop, we do not add a condition to end the loop, the cursor will keep looking for records, when there is no record, will throw exception 1329: did not get the number of rows selected for processing.
What if we wanted to specify conditions that would end the loop?
You can declare a Boolean tag at this point. True queries the result set, false terminates the loop.
delimiter // create procedure f() begin declare val_id int; declare val_name varchar(32); declare val_salary double; Flag flag Boolean Default true; # declare emp_flag cursor for SELECT ID, name, salary from employee; # open emp_flag; C :loop fetch emp_flag into val_id, val_name, val_salary; If flag then select val_id, val_name, val_salary; Leave c; leave c; end if; end loop; # close emp_flag; select val_id, val_name, val_salary; end // call f();Copy the code
As you can see, the above code is not finished, and it leaves a serious problem. End the loop when flag = false. But when do you set flag to false?
So MySQL provides us with a handler handle. It can help us solve this puzzle.
Handler handler syntax: Declare continue handler for exception set flag = false;
Handler handles can be used to catch exceptions, that is, in this scenario change the value of the flag flag to false when 1329: does not fetch the number of rows selected for processing. This solves the problem of ending the loop using handler handles. Let’s try it!
Ultimate example: solved multi-line query and end loop problems.
delimiter // create procedure f() begin declare val_id int; declare val_name varchar(32); declare val_salary double; Flag flag Boolean Default true; # declare emp_flag cursor for SELECT ID, name, salary from employee; Declare continue handler for 1329 set flag = false; declare continue handler for 1329 set flag = false; # open emp_flag; C :loop fetch emp_flag into val_id, val_name, val_salary; If flag then select val_id, val_name, val_salary; Leave c; leave c; end if; end loop; # close emp_flag; select val_id, val_name, val_salary; end // call f();Copy the code
Execution Result:
In the execution result, it can be seen that the query result is distributed in each query result window in the form of multiple queries.
Note: In syntax, variable declarations, cursor declarations, and handler declarations must be written in order, otherwise the stored procedure will fail to be created.
5.2 handle handler
Grammar:
DECLARE handleroperationHANDLER
FORCase list... (for example: exception error condition) operation statementCopy the code
Note: Exception cases can be written to exception error codes, exception aliases, or SQLSTATE codes.
Handler:
- CONTINUE, CONTINUE to
- EXIT, EXIT
- UNDO: removed
List of exceptions:
- mysql_error_code
- SQLSTATE [VALUE] sqlstate_value
- condition_name
- SQLWARNING
- NOT FOUND
- SQLEXCEPTION
Note: The various exception codes, error codes, aliases and SQLSTATEM codes in MySQL can be found in the official documentation:
Dev.mysql.com/doc/refman/…
Example of writing:
DECLARE exit HANDLER FOR SQLSTATE '3D000' set flag = false;
DECLARE continue HANDLER FOR 1050 set flag = false;
DECLARE continue HANDLER FOR not found set flag = false;
Copy the code
Create tables in a loop
Requirement: Create a table for each day of the next month, comp_2020_06_01, comp_2020_06_02,…
Description: We need to use a table to record a lot of data, such as record so-and-so users search, purchase behavior (note that this is a hypothesis with a database to store), when the record is large, every day if put all data records to a table is too large, need table, our request is that one table every day, the statistics of the day, Just ask to produce these tables ahead of time — create the next day’s tables at the end of each month!
Precompile: PREPARE database object name FROM parameter name
EXECUTE: EXECUTE the name of the database object [USING @var_name [, @var_name]…
Through a database object to create or delete table: {DEALLOCATE | DROP} PREPARE database object names
Time processing statements:
EXTRACT(unit FROM date) EXTRACT(unit FROM date
-- DATE_ADD(date,INTERVAL expr Unit) Date calculation
-- LAST_DAY(date) Indicates the last day to obtain the date
-- YEAR(date) Returns the YEAR in the date
-- MONTH(date) Returns the MONTH of the date
-- DAYOFMONTH(date) Returns the day
Copy the code
Code:
Comp_2020_06_01 to comp_2020_06_30; And execute the CREATE statement. Delimiter // create PROCEDURE SP_CREATE_TABLE () BEGIN # Declare next_year int; delimiter create PROCEDURE SP_CREATE_TABLE () BEGIN # Declare next_year int; declare next_month int; declare next_month_day int; # declare next_month_str char(2); declare next_month_day_str char(2); Declare table_name_str char(10); 1 declare T_index int default 1; # declare create_table_sql varchar(200); Set next_year = year(date_add(now(),INTERVAL 1 month)); Set next_month = month(date_add(now(),INTERVAL 1 month)); Set next_month_day = dayofmonth(LAST_DAY(date_add(now(),INTERVAL 1 month))); # if next_month_str = concat('0',next_month) # if next_month_str = concat('0', next_month_str); Set next_month_str = concat(",next_month); end if; While t_index <= next_month_day do # if (t_index < 10) then set 0 next_month_day_str = concat('0',t_index); Set next_month_day_str = concat('',t_index); end if; Set table_month_str = concat(next_year,'_',next_month_str,'_',next_month_day_str); Set @create_table_sql = concat('create table comp_', table_name_str, '(`grade` INT(11) NULL,`losal` INT(11) NULL,`hisal` INT(11) NULL) COLLATE=\'utf8_general_ci\' ENGINE=InnoDB'); Note: Local variables cannot be used after FROM! prepare create_table_stmt FROM @create_table_sql; Execute create_table_stmt; DEALLOCATE prepare create_table_stmt; Set t_index = t_index + 1; end while; Call sp_create_table()Copy the code
Seven, other
7.1 characteristic
MySQL stored procedures create stored procedures that implicitly define the default values of a set of characteristics if they are not shown characteristic.
LANGUAGE SQL
- The stored procedure language is SQL by default. It indicates that the stored procedure is written in SQL. Only SQL is supported for the time being, and other languages may be supported later
NOT DETERMINISTIC
- DETERMINISTIC input is DETERMINISTIC output, default is NOT DETERMINISTIC, output is the same only for the same input, this value is NOT used yet
CONTAINS SQL
- Provides intrinsic information about the subroutine usage data, which is currently provided to the server and does not constrain the actual use of the data by the process based on these eigenvalues. The options are as follows:
- CONTAINS SQL indicates that a subroutine does not contain statements that read or write data
- NO SQL Indicates that the subroutine does not contain SQL
- READS SQL DATA indicates that the subroutine contains statements that read DATA, but does not contain statements that write DATA
- MODIFIES SQL DATA indicates that the subroutine contains statements to write DATA.
SQL SECURITY DEFINER
- MySQL stored procedures specify the actual user who executes the stored procedure by specifying the SQL SECURITY clause. So the secondary value is used to specify whether the stored procedure is executed with the permission of the author or the permission of the executor. The default value is DEFINER
- DEFINER as the creator. For the current user: the current user can successfully execute the procedure call if the stored procedure permission is executed and the creator has access to the table
- INVOKER caller to execute, for the current user: if the permission to execute the stored procedure, with the current identity to access the table, if the current identity does not have access to the table, even if there is the permission to execute the procedure, it is still unable to successfully execute the procedure call.
COMMENT ”
- The comments of stored procedures are written in comments, which can only be single-line text, and multi-line text will be removed to carriage return and line feed
7.2 Dead loop processing
If there is an infinite loop, you can view and kill (end) with the following command
show processlist;
kill id;
Copy the code
7.3 Writing a case in the SELECT Statement
select
case
whenconditionalthenThe results ofwhenconditionalthenThe results ofelseThe results ofendAlias, *fromThe name of the table.Copy the code
7.4 Copying tables and Data
CREATE TABLE dept SELECT * FROM procedure_demo.dept;
CREATE TABLE emp SELECT * FROM procedure_demo.emp;
CREATE TABLE salgrade SELECT * FROM procedure_demo.salgrade;
Copy the code
7.5 the temporary table
create temporary tableThe name of the table (& emsp;   Field name type [constraint],     name varchar(20) )Engine=InnoDB default charset utf8;-- Requirement: Query employees by department name, and run the select command to view employee id, name, and salary. (Note that cursor usage is only demonstrated here.)
delimiter ?
create procedure sp_create_table02(in dept_name varchar(32))
begin
declare emp_no int;
declare emp_name varchar(32);
declare emp_sal decimal(7.2);
declare exit_flag int default 0;
declare emp_cursor cursor for
select e.empno,e.ename,e.sal
from emp e inner join dept d on e.deptno = d.deptno where d.dname = dept_name;
declare continue handler for not found set exit_flag = 1;
Create temporary tables to collect data
CREATE temporary TABLE `temp_table_emp` (
`empno` INT(11) NOT NULL COMMENT 'Staff No.'.`ename` VARCHAR(32) NULL COMMENT 'Name of Employee' COLLATE 'utf8_general_ci'.`sal` DECIMAL(7.2) NOT NULL DEFAULT '0.00' COMMENT 'salaries',
PRIMARY KEY (`empno`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB; open emp_cursor; c_loop:loop fetch emp_cursor into emp_no,emp_name,emp_sal; if exit_flag ! = 1 theninsert into temp_table_emp values(emp_no,emp_name,emp_sal);
else
leave c_loop;
end if;
end loop c_loop;
select * from temp_table_emp;
select @sex_res; -- Just to see if it works
close emp_cursor;
end?
call sp_create_table02('RESEARCH');
Copy the code
Article different GitHub address: github.com/Ziphtracks/… Welcome to Star!