Dynamic SQL allows SQL code to be constructed and executed dynamically at runtime. It is particularly useful in situations where SQL queries must be generated dynamically, such as when table names, columns, or other parameters are not known in advance. However, it must be handled with caution to prevent SQL injection vulnerabilities.
Example Usage of Dynamic SQL
1. Declaring Variables and Executing a Simple Query
-- Declare a variable for a specific value
DECLARE @Spec_LTP VARCHAR(75); -- varchar limit is up to 255
SET @Spec_LTP = 6.20;
-- Execute a query with the variable
SELECT * FROM [CSEDB].[dbo].[Prices] WHERE LTP = @Spec_LTP;
2. Printing and Executing Queries
-- Declare variables for dynamic SQL
DECLARE @Select NVARCHAR(75) = 'SELECT * FROM ';
DECLARE @TableName NVARCHAR(50) = '[CSEDB].[dbo].[Prices]';
-- Print the query
PRINT(@Select + @TableName);
-- Execute the query
EXEC(@Select + @TableName);
3. Writing a Simple Query Using Dynamic SQL
DECLARE @TableName2 NVARCHAR(50) = '[CSEDB].[dbo].[Prices]';
-- Execute a query dynamically
EXEC('SELECT * FROM ' + @TableName2);
4. Creating a Stored Procedure for Dynamic SQL
Create Procedure
GO
CREATE PROC GeneralQuery @TableName3 NVARCHAR(50)
AS
BEGIN
DECLARE @SQL NVARCHAR(1000);
SET @SQL = 'SELECT * FROM ' + @TableName3;
EXEC (@SQL);
END
GO
Execute the Stored Procedure
EXEC GeneralQuery '[CSEDB].[dbo].[Prices]';
EXEC GeneralQuery '[CSEDB].[dbo].[Companies]';
5. Altering (Editing) an Existing Stored Procedure
Alter Procedure
GO
ALTER PROC GeneralQuery @TableName3 NVARCHAR(50)
AS
BEGIN
DECLARE @SQL NVARCHAR(1000);
SET @SQL = 'SELECT * FROM ' + @TableName3;
-- Print the query for debugging purposes
PRINT (@SQL);
-- Execute the query
EXEC (@SQL);
END
GO
Execute the Altered Stored Procedure
EXEC GeneralQuery '[CSEDB].[dbo].[Prices]';
EXEC GeneralQuery '[CSEDB].[dbo].[Companies]';
6. Checking and Dropping Stored Procedures
List All Procedures for Manual Dropping
SELECT 'DROP PROCEDURE [' + SCHEMA_NAME(p.schema_id) + '].[' + p.name + '];'
FROM sys.procedures p;
Drop a Single Procedure
DROP PROCEDURE [dbo].[GetBookBorrowers];
Drop All Procedures at Once
DECLARE @procName VARCHAR(500);
DECLARE cur CURSOR FOR
SELECT [name]
FROM sys.objects
WHERE type = 'P';
OPEN cur;
FETCH NEXT FROM cur INTO @procName;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC('DROP PROCEDURE [' + @procName + ']');
FETCH NEXT FROM cur INTO @procName;
END;
CLOSE cur;
DEALLOCATE cur;
Key Considerations
-
Security Risks:
- Dynamic SQL can be vulnerable to SQL injection if user inputs are directly included in the query.
- Always sanitize inputs or use
sp_executesql
with parameterized queries for enhanced security.
-
Debugging:
- Use
PRINT
statements to output the dynamically generated SQL query to debug issues.
- Use
-
Flexibility:
- Dynamic SQL is ideal for scenarios where table names or columns need to be passed dynamically.
-
Performance:
- Queries executed via dynamic SQL may not benefit from cached execution plans, which could impact performance.
-
Best Practices:
- Limit the use of dynamic SQL to scenarios where no alternative exists.
- Always use
sp_executesql
to parameterize input values when possible.