Calling Stored Procedures using Connector/Python
Last updated on July 27, 2020
What is Stored Procedure? #
A Stored procedure is simply a set of SQL statements grouped together and given a name. Stored procedures are used in situations where you want to execute the same set of statements multiple number of times. We create stored procedures using the CREATE PROCEDURE
statement. Stored procedures can also accept arguments. Once the stored procedure is created, we can invoke it using the CALL
statement followed by the procedure name, followed by arguments (if any) inside the parentheses.
Here is a simple stored procedure that accepts a continent and returns the name of the countries in it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | mysql> use world;
mysql>
mysql> DELIMITER //
mysql> CREATE PROCEDURE get_country_by_continent
-> (
-> IN con CHAR(20)
-> )
-> BEGIN
-> SELECT Name
-> FROM country
-> WHERE Continent = con;
-> END //
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql>
|
Note that in the preceding snippet the con
argument is preceded with the IN
keyword, thus it is an input parameter. An input parameter is used to pass values to the stored procedure from the calling program. A stored procedure can change the value of the input parameter but this change will be not visible to calling the program when the procedure returns. If you want to return values from the stored procedures then declare the parameter as output parameter using the OUT
keyword instead of IN
. The initial value of the output parameter is NULL
.
In addition to input and output parameters, there exists another kind parameter called input/output parameter. As the name suggests, an input/output parameter can be used as an input parameter as well as an output parameter. In other words, input/output parameter can be used to pass values to the stored procedures. Further, a stored procedure can modify the input/output parameter and return it to the calling program. To create input/output parameter precede the variable name with the INOUT
keyword.
Let's create a stored procedure that uses both input and output parameters.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | mysql>
mysql> DELIMITER //
mysql> CREATE PROCEDURE get_country_info
-> (
-> IN country CHAR(20),
-> OUT info VARCHAR(200)
-> )
-> BEGIN
-> SELECT CONCAT_WS(":", Name, Continent, Population, LifeExpectancy, HeadOfState)
-> INTO info
-> FROM country
-> WHERE Name = country;
->
-> select city.Name, city.Population, city.District from city
-> INNER JOIN country
-> where city.CountryCode = country.Code and country.Name= country
-> order by Population desc limit 10;
->
-> END //
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql>
|
Here is how this stored procedure works:
The stored procedure accepts two arguments:
country
andinfo
. Thecountry
is the input parameter andinfo
is the output parameter.Next, we use the
SELECT
statement to fetch some relevant data about the country. To store the data into the output parameter we use theINTO
clause.Finally, we print the top 10 populated cities of the country in descending order.
We now have two stored procedures in the world
database. To view them type the following command:
1 2 3 4 5 6 7 8 9 10 | mysql> show PROCEDURE STATUS where db = "world";
+-------+--------------------------+-----------+----------------+---------------------+---------------------+
| Db | Name | Type | Definer | Modified | Created |
+-------+--------------------------+-----------+----------------+---------------------+---------------------+
| world | get_country_by_continent | PROCEDURE | root@localhost | 2018-10-05 10:28:37 | 2018-10-05 10:28:37 |
| world | get_country_info | PROCEDURE | root@localhost | 2018-10-05 11:25:35 | 2018-10-05 11:25:35 |
+-------+--------------------------+-----------+----------------+---------------------+---------------------+
2 rows in set (0.01 sec)
mysql>
|
Note: Some columns are in preceding output is omitted to save the space.
To call the get_country_by_continent
stored procedure use the CALL
statement as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | mysql>
mysql> CALL get_country_by_continent("South America");
+------------------+
| Name |
+------------------+
| Argentina |
| Bolivia |
| Brazil |
| Chile |
| Colombia |
| Ecuador |
| Falkland Islands |
| French Guiana |
| Guyana |
| Peru |
| Paraguay |
| Suriname |
| Uruguay |
| Venezuela |
+------------------+
14 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
|
Similarly, we can call get_country_info
as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | mysql>
mysql> call get_country_info("Brazil", @info);
+----------------+------------+-------------------+
| Name | Population | District |
+----------------+------------+-------------------+
| São Paulo | 9968485 | São Paulo |
| Rio de Janeiro | 5598953 | Rio de Janeiro |
| Salvador | 2302832 | Bahia |
| Belo Horizonte | 2139125 | Minas Gerais |
| Fortaleza | 2097757 | Ceará |
| Brasília | 1969868 | Distrito Federal |
| Curitiba | 1584232 | Paraná |
| Recife | 1378087 | Pernambuco |
| Porto Alegre | 1314032 | Rio Grande do Sul |
| Manaus | 1255049 | Amazonas |
+----------------+------------+-------------------+
10 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
|
Notice how the output parameter (i.e @info
) is passed to the procedure. After the procedure executes, we can print the value of the output parameter using the SELECT
statement as follows:
1 2 3 4 5 6 7 8 9 10 | mysql>
mysql> select @info;
+---------------------------------------------------------------+
| @info |
+---------------------------------------------------------------+
| Brazil:South America:170115000:62.9:Fernando Henrique Cardoso |
+---------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
|
Calling Stored Procedures with callproc() #
To call stored procedures we use the callproc()
method of the cursor object. The syntax of the callproc()
method is as follows:
callproc(proc_name, args=())
Argument | Description |
---|---|
proc_name |
The stored procedure you want to call |
args |
A sequence of arguments to pass to the stored procedure |
On success, the callproc()
returns a modified version of the input sequence. The input parameters (i.e. parameter coded with the IN
keyword ) are left untouched but the input and output parameters (i.e. parameters coded with the OUT
and INOUT
keyword, respectively) may contain new values.
Once the stored procedure is executed, you can fetch the results using the stored_results()
method of the cursor object. The stored_results()
returns an iterator which can be used to iterate over the rows in the result set.
It is important to note that the result set produced by the stored procedure is fetched immediately and stored as MySQLCursorBuffered
instances.
The following listing demonstrates how to use the callproc()
in action:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import mysql.connector
from pprint import pprint
db = mysql.connector.connect(option_files='my.conf')
cursor = db.cursor()
args = cursor.callproc('get_country_by_continent', ('South America',) )
print("Return value:", args)
for result in cursor.stored_results():
pprint(result.fetchall())
print('-' * 100)
args = cursor.callproc('get_country_info', ('Japan', None) )
print("Return value:", args)
for result in cursor.stored_results():
pprint(result.fetchall())
|
Expected Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Return value: ('South America',)
[('Argentina',),
('Bolivia',),
('Brazil',),
('Chile',),
('Colombia',),
('Ecuador',),
('Falkland Islands',),
('French Guiana',),
('Guyana',),
('Peru',),
('Paraguay',),
('Suriname',),
('Uruguay',),
('Venezuela',)]
----------------------------------------------------------------------------------------------------
Return value: ('Japan', 'Japan:Asia:126714000:80.7:Akihito')
[('Tokyo', 7980230, 'Tokyo-to'),
('Jokohama [Yokohama]', 3339594, 'Kanagawa'),
('Osaka', 2595674, 'Osaka'),
('Nagoya', 2154376, 'Aichi'),
('Sapporo', 1790886, 'Hokkaido'),
('Kioto', 1461974, 'Kyoto'),
('Kobe', 1425139, 'Hyogo'),
('Fukuoka', 1308379, 'Fukuoka'),
('Kawasaki', 1217359, 'Kanagawa'),
('Hiroshima', 1119117, 'Hiroshima')]
|
Notice that in the second call to callproc()
method, we are passing None
as the second argument this is because the get_country_info
stored produced accepts two arguments (one input and one output).
Load Comments