Stored procedures for T-SQL
This topic provides reference content comparing stored procedures in Microsoft SQL Server 2019 and Amazon Aurora MySQL. You can understand the key differences and similarities between these two database systems' implementations of stored procedures.
Feature compatibility | AWS SCT / AWS DMS automation level | AWS SCT action code index | Key differences |
---|---|---|---|
|
|
No support for table-valued parameters. Syntax and option differences. |
SQL Server Usage
Stored procedures are encapsulated, persisted code modules you can run using the EXECUTE
T-SQL statement. They may have multiple input and output parameters. Table-valued user-defined types can
be used as input parameters. IN is the default direction for parameters, but OUT
must be explicitly specified. You can specify parameters as both IN
and OUT
.
In SQL Server, you can run stored procedures in any security context using the EXECUTE AS
option. They can be explicitly recompiled for every run using the RECOMPILE option and can be encrypted in the database using the ENCRYPTION
option to prevent unauthorized access to the source code.
SQL Server provides a unique feature that allows you to use a stored procedure as an input to an INSERT
statement. When you use this feature, only the first row in the data set returned by the stored procedure is evaluated.
As part of the stored procedure syntax, SQL Server supports a default output integer parameter that can be specified along with the RETURN
command, for example, RETURN -1
. It’s typically used to signal status or error to the calling scope, which can use the syntax EXEC @Parameter = <Stored Procedure Name>
to retrieve the RETURN
value, without explicitly stating it as part of the parameter list.
Syntax
CREATE [ OR ALTER ] { PROC | PROCEDURE } <Procedure Name> [<Parameter List> [ WITH [ ENCRYPTION ]|[ RECOMPILE ]|[ EXECUTE AS ...]] AS { [ BEGIN ] <SQL Code Body> [RETURN [<Integer Value>]] [ END ] }[;]
Creating and Running a Stored Procedure
Create a simple parameterized stored procedure to validate the basic format of an email.
CREATE PROCEDURE ValidateEmail @Email VARCHAR(128), @IsValid BIT = 0 OUT AS BEGIN IF @Email LIKE N'%@%' SET @IsValid = 1 ELSE SET @IsValid = 0 RETURN END;
Run the procedure.
DECLARE @IsValid BIT EXECUTE [ValidateEmail] @Email = 'X@y.com', @IsValid = @IsValid OUT; SELECT @IsValid; -- Returns 1
EXECUTE [ValidateEmail] @Email = 'Xy.com', @IsValid = @IsValid OUT; SELECT @IsValid; -- Returns 0
Create a stored procedure that uses RETURN
to pass the application an error value.
CREATE PROCEDURE ProcessImportBatch @BatchID INT AS BEGIN BEGIN TRY EXECUTE Step1 @BatchID EXECUTE Step2 @BatchID EXECUTE Step3 @BatchID END TRY BEGIN CATCH IF ERROR_NUMBER() = 235 RETURN -1 -- indicate special condition ELSE THROW -- handle error normally END CATCH END
Using a Table-Valued Input Parameter
Create and populate the OrderItems
table.
CREATE TABLE OrderItems( OrderID INT NOT NULL, Item VARCHAR(20) NOT NULL, Quantity SMALLINT NOT NULL, PRIMARY KEY(OrderID, Item) );
INSERT INTO OrderItems (OrderID, Item, Quantity) VALUES (1, 'M8 Bolt', 100), (2, 'M8 Nut', 100), (3, 'M8 Washer', 200), (3, 'M6 Washer', 100);
Create a table-valued type for the OrderItem
table-valued parameter.
CREATE TYPE OrderItems AS TABLE ( OrderID INT NOT NULL, Item VARCHAR(20) NOT NULL, Quantity SMALLINT NOT NULL, PRIMARY KEY(OrderID, Item) );
Create a procedure to process order items.
CREATE PROCEDURE InsertOrderItems @OrderItems AS OrderItems READONLY AS BEGIN INSERT INTO OrderItems(OrderID, Item, Quantity) SELECT OrderID, Item, Quantity FROM @OrderItems END;
Instantiate and populate the table valued variable and pass the data set to the stored procedure.
DECLARE @OrderItems AS OrderItems; INSERT INTO @OrderItems ([OrderID], [Item], [Quantity]) VALUES (1, 'M8 Bolt', 100), (1, 'M8 Nut', 100), (1, M8 Washer, 200); EXECUTE [InsertOrderItems] @OrderItems = @OrderItems; (3 rows affected) Item Quantity 1 M8 Bolt 100 2 M8 Nut 100 3 M8 Washer 200
INSERT… EXEC Syntax
INSERT INTO <MyTable> EXECUTE <MyStoredProcedure>;
For more information, see CREATE PROCEDURE (Transact-SQL)
MySQL Usage
Amazon Aurora MySQL-Compatible Edition (Aurora MySQL) stored procedures provide similar functionality to SQL Server stored procedures.
As with SQL Server, Aurora MySQL supports security run context. It also supports input, output, and bi-directional parameters.
Stored procedures are typically used for: * Code reuse — Stored procedures offer a convenient code encapsulation and reuse mechanism for multiple applications, potentially written in various languages, requiring the same database operations. * Security management — By allowing access to base tables only through stored procedures, administrators can manage auditing and access permissions. This approach minimizes dependencies between application code and database code. Administrators can use stored procedures to process business rules and to perform auditing and logging. * Performance improvements — Full SQL query text doesn’t need to be transferred from the client to the database.
Stored procedures, triggers, and user-defined functions in Aurora MySQL are collectively referred to as stored routines. When binary logging is enabled, MySQL SUPER
privilege is required to run stored routines. However, you can run stored routines with binary logging enabled without SUPER
privilege by setting thelog_bin_trust_function_creators
parameter to true for the DB parameter group for your MySQL instance.
Aurora MySQL permits stored routines to contain control flow, DML, DDL, and transaction management statements including START TRANSACTION
, COMMIT
, and ROLLBACK
.
Syntax
CREATE [DEFINER = { user | CURRENT_USER }] PROCEDURE sp_name ([ IN | OUT | INOUT ] <Parameter> <Parameter Data Type> ... ) COMMENT 'string' | LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } <Stored Procedure Code Body>
Examples
Replace RETURN value parameter with standard OUTPUT parameters.
CREATE PROCEDURE ProcessImportBatch() IN @BatchID INT, OUT @ErrorNumber INT BEGIN CALL Step1 (@BatchID) CALL Step2 (@BatchID) CALL Step3 (@BatchID) IF error_count > 1 SET @ErrorNumber = -1 -- indicate special condition END
Use a LOOP
cursor with a source table to replace table valued parameters.
Create the OrderItems
table.
CREATE TABLE OrderItems ( OrderID INT NOT NULL, Item VARCHAR(20) NOT NULL, Quantity SMALLINT NOT NULL, PRIMARY KEY(OrderID, Item) );
Create and populate SourceTable
as a temporary data store for incoming rows.
CREATE TABLE SourceTable ( OrderID INT, Item VARCHAR(20), Quantity SMALLINT, PRIMARY KEY (OrderID, Item) );
INSERT INTO SourceTable (OrderID, Item, Quantity) VALUES (1, 'M8 Bolt', 100), (2, 'M8 Nut', 100), (3, 'M8 Washer', 200);
Create a procedure to loop through all rows in SourceTable
and insert them into the OrderItems
table.
CREATE PROCEDURE LoopItems() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE var_OrderID INT; DECLARE var_Item VARCHAR(20); DECLARE var_Quantity SMALLINT; DECLARE ItemCursor CURSOR FOR SELECT OrderID, Item, Quantity FROM SourceTable; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN ItemCursor; CursorStart: LOOP FETCH NEXT FROM ItemCursor INTO var_OrderID, var_Item, var_Quantity; IF Done THEN LEAVE CursorStart; END IF; INSERT INTO OrderItems (OrderID, Item, Quantity) VALUES (var_OrderID, var_Item, var_Quantity); END LOOP; CLOSE ItemCursor; END;
Call the stored procedure.
CALL LoopItems();
Select all rows from the OrderItems table.
SELECT * FROM OrderItems;
For the preceding example, the result looks as shown following.
OrderID Item Quantity 1 M8 Bolt 100 2 M8 Nut 100 3 M8 Washer 200
Summary
The following table summarizes the differences between MySQL Stored Procedures and SQL Server Stored Procedures.
Feature | SQL Server | Aurora MySQL | Workaround |
---|---|---|---|
General |
CREATE PROC|PROCEDURE <Procedure Name> @Parameter1 <Type>, ...n AS <Body> |
CREATE PROCEDURE <Procedure Name> (Parameter1 <Type>,...n) <Body> |
Rewrite stored procedure creation scripts to use Rewrite stored procedure creation scripts to omit the Rewrite stored procedure parameters to not use the Rewrite stored procedure parameter direction |
Security context |
{ EXEC | EXECUTE } AS { CALLER | SELF | OWNER | 'user_name' } |
DEFINER = 'user' | CURRENT_USER in conjunction with SQL SECURITY {
DEFINER | INVOKER }
|
For stored procedures that use an explicit user name, rewrite the code from For stored procedures that use the For stored procedures that use the Unlike SQL Server, |
Encryption |
Use the |
Not supported in Aurora MySQL. |
|
Parameter direction |
|
|
Although the functionality of these parameters is the same for SQL Server and MySQL, make sure that you rewrite the code for syntax compliance. Use Use |
Recompile |
Use the |
Not supported in Aurora MySQL. |
|
Table-valued parameters |
Use declared table type user-defined parameters. |
Not supported in Aurora MySQL. |
See the preceding example for a workaround. |
|
Use the output of the stored procedure as input to an |
Not supported in Aurora MySQL. |
Use tables to hold the data or pass string parameters formatted as CSV, XML, JSON (or any other convenient format) and then parse the parameters before the |
Additional restrictions |
Use |
The LOAD DATA statement isn’t allowed in stored procedures. |
|
|
|
Not supported. |
Use a standard |
For more information, see Stored Procedures and Functions