{"id":166,"date":"2019-09-24T08:01:17","date_gmt":"2019-09-24T08:01:17","guid":{"rendered":"http:\/\/sumitjangid.com\/?p=166"},"modified":"2019-09-24T08:03:46","modified_gmt":"2019-09-24T08:03:46","slug":"dynamic-sql","status":"publish","type":"post","link":"http:\/\/sumitjangid.com\/index.php\/2019\/09\/24\/dynamic-sql\/","title":{"rendered":"Dynamic SQL"},"content":{"rendered":"\n<h2>Introduction to Dynamic SQL<\/h2>\n\n\n\n<p>Dynamic SQL is a programming technique that allows you to construct SQL statements dynamically at runtime. It allows you to create more general purpose and flexible SQL statement because the full text of the SQL statements may be unknown at compilation. For example, you can use the dynamic SQL to&nbsp;<a href=\"http:\/\/www.sqlservertutorial.net\/sql-server-stored-procedures\/\">create a stored procedure<\/a>&nbsp;that queries data against a table whose name is not known until runtime.<\/p>\n\n\n\n<p>Creating a dynamic SQL is simple, you just need to make it a string as follows:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>&#8216;SELECT * FROM production.products&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>To execute a dynamic SQL statement, you call the stored procedure&nbsp;<code>sp_executesql<\/code>&nbsp;as shown in the following statement:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>EXEC sp_executesql N&#8217;SELECT * FROM production.products&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Because the&nbsp;<code>sp_executesql<\/code>&nbsp;accepts the dynamic SQL as a Unicode string, you need to prefix it with an&nbsp;<code>N<\/code>.<\/p>\n\n\n\n<p>Though this dynamic SQL is not very useful, it illustrates a dynamic SQL very well.<\/p>\n\n\n\n<h3>Using dynamic SQL to query from any table example<\/h3>\n\n\n\n<p>First, declare two variables,&nbsp;<code>@table<\/code>&nbsp;for holding the name of the table from which you want to query and&nbsp;<code>@sql<\/code>&nbsp;for holding the dynamic SQL.<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>123<\/td><td>DECLARE &nbsp;&nbsp;&nbsp;&nbsp;@table NVARCHAR(128),&nbsp;&nbsp;&nbsp;&nbsp;@sql NVARCHAR(MAX);<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Second, set the value of the&nbsp;<code>@table<\/code>&nbsp;variable to&nbsp;<code>production.products<\/code>.<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>SET @table = N&#8217;production.products&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Third, construct the dynamic SQL by concatenating the&nbsp;<code>SELECT<\/code>&nbsp;statement with the table name parameter:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>SET @sql = N&#8217;SELECT * FROM &#8216; + @table;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Fourth, call the&nbsp;<code>sp_executesql<\/code>&nbsp;stored procedure by passing the&nbsp;<code>@sql<\/code>&nbsp;parameter.<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>EXEC sp_executesql @sql;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Putting it all together:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>123456789<\/td><td>DECLARE &nbsp;&nbsp;&nbsp;&nbsp;@table NVARCHAR(128),&nbsp;&nbsp;&nbsp;&nbsp;@sql NVARCHAR(MAX);&nbsp;SET @table = N&#8217;production.products&#8217;;&nbsp;SET @sql = N&#8217;SELECT * FROM &#8216; + @table;&nbsp;EXEC sp_executesql @sql;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>The code block above produces the exact result set as the following statement:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>SELECT * FROM production.products;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>To query data from another table, you change the value of the&nbsp;<code>@table<\/code>&nbsp;variable. However, it\u2019s more practical if we wrap the above T-SQL block in a stored procedure.<\/p>\n\n\n\n<h3>SQL Server dynamic SQL and stored procedures<\/h3>\n\n\n\n<p>This stored procedure accepts any table and returns the result set from a specified table by using the dynamic SQL:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>12345678910111213<\/td><td>CREATE PROC usp_query (&nbsp;&nbsp;&nbsp;&nbsp;@table NVARCHAR(128))ASBEGIN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DECLARE @sql NVARCHAR(MAX);&nbsp;&nbsp;&nbsp;&nbsp;<em>&#8212; construct SQL<\/em>&nbsp;&nbsp;&nbsp;&nbsp;SET @sql = N&#8217;SELECT * FROM &#8216; + @table;&nbsp;&nbsp;&nbsp;&nbsp;<em>&#8212; execute the SQL<\/em>&nbsp;&nbsp;&nbsp;&nbsp;EXEC sp_executesql @sql;&nbsp;&nbsp;&nbsp;&nbsp;END;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>The following statement calls the&nbsp;<code>usp_query<\/code>&nbsp;stored procedure to return all rows from the&nbsp;<code>production.brands<\/code>&nbsp;table:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>EXEC usp_query &#8216;production.brands&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>This stored procedure returns the top 10 rows from a table by the values of a specified column:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>123456789101112131415161718192021<\/td><td>CREATE OR ALTER PROC usp_query_topn(&nbsp;&nbsp;&nbsp;&nbsp;@table NVARCHAR(128),&nbsp;&nbsp;&nbsp;&nbsp;@topN INT,&nbsp;&nbsp;&nbsp;&nbsp;@byColumn NVARCHAR(128))ASBEGIN&nbsp;&nbsp;&nbsp;&nbsp;DECLARE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@sql NVARCHAR(MAX),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@topNStr NVARCHAR(MAX);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET @topNStr&nbsp;&nbsp;= CAST(@topN as nvarchar(max));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>&#8212; construct SQL<\/em>&nbsp;&nbsp;&nbsp;&nbsp;SET @sql = N&#8217;SELECT TOP &#8216; +&nbsp;&nbsp;@topNStr&nbsp;&nbsp;+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216; * FROM &#8216; + @table + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216; ORDER BY &#8216; + @byColumn + &#8216; DESC&#8217;;&nbsp;&nbsp;&nbsp;&nbsp;<em>&#8212; execute the SQL<\/em>&nbsp;&nbsp;&nbsp;&nbsp;EXEC sp_executesql @sql;&nbsp;&nbsp;&nbsp;&nbsp;END;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>For example, you can get the top 10 most expensive products from the&nbsp;<code>production.products<\/code>&nbsp;table:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1234<\/td><td>EXEC usp_query_topn &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;production.products&#8217;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;list_price&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>This statement returns the top 10 products with the highest quantity in stock:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1234<\/td><td>EXEC usp_query_topn &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;production.tocks&#8217;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;quantity&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<h2>SQL Server Dynamic SQL and SQL Injection<\/h2>\n\n\n\n<p>Let\u2019s&nbsp;<a href=\"http:\/\/www.sqlservertutorial.net\/sql-server-basics\/sql-server-create-table\/\">create a new table<\/a>&nbsp;named&nbsp;<code>sales.tests<\/code>&nbsp;for the demonstration:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>CREATE TABLE sales.tests(id INT); <\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>This statement returns all rows from the&nbsp;<code>production.brands<\/code>&nbsp;table:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>EXEC usp_query &#8216;production.brands&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>But it does not prevent users from passing the table name as follows:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>EXEC usp_query &#8216;production.brands;DROP TABLE sales.tests&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>This technique is called SQL injection. Once the statement is executed, the&nbsp;<code>sales.tests<\/code>&nbsp;table is dropped, because the stored procedure&nbsp;<code>usp_query<\/code>&nbsp;executes both statements:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>SELECT * FROM production.brands;DROP TABLE sales.tests<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>To prevent this SQL injection, you can use the&nbsp;<code><a href=\"http:\/\/www.sqlservertutorial.net\/sql-server-string-functions\/sql-server-quotename-function\/\">QUOTENAME()<\/a><\/code>&nbsp;function as shown in the following query:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1234567891011121314151617<\/td><td>CREATE OR ALTER PROC usp_query(&nbsp;&nbsp;&nbsp;&nbsp;@schema NVARCHAR(128), &nbsp;&nbsp;&nbsp;&nbsp;@table&nbsp;&nbsp;NVARCHAR(128))AS&nbsp;&nbsp;&nbsp;&nbsp;BEGIN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DECLARE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@sql NVARCHAR(MAX);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>&#8212; construct SQL<\/em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET @sql = N&#8217;SELECT * FROM &#8216; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ QUOTENAME(@schema) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ &#8216;.&#8217; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ QUOTENAME(@table);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>&#8212; execute the SQL<\/em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXEC sp_executesql @sql;&nbsp;&nbsp;&nbsp;&nbsp;END;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Now, if you pass the schema and table name to the stored procedure, it will work:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>EXEC usp_query &#8216;production&#8217;,&#8217;brands&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>However, if you try to inject another statement such as:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>123<\/td><td>EXEC usp_query &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;production&#8217;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;brands;DROP TABLE sales.tests&#8217;;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>It will issue the following error:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td>Invalid object name &#8216;production.brands;DROP TABLE sales.tests&#8217;.<\/td><\/tr><\/tbody><\/table>\n\n\n\n<h2>More on&nbsp;<code>sp_executesql<\/code>&nbsp;stored procedure<\/h2>\n\n\n\n<p>The&nbsp;<code>sp_executesql<\/code>&nbsp;has the following syntax:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>123456<\/td><td>EXEC sp_executesql &nbsp;&nbsp;&nbsp;&nbsp;sql_statement&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameter_definition&nbsp;&nbsp;&nbsp;&nbsp;@param1 = value1,&nbsp;&nbsp;&nbsp;&nbsp;@param2 = value2,&nbsp;&nbsp;&nbsp;&nbsp;&#8230;<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>In this syntax:<\/p>\n\n\n\n<ul><li><code>sql_statement<\/code>&nbsp;is a Unicode string that contains a T-SQL statement. The&nbsp;<code>sql_statement<\/code>&nbsp;can contain parameters such as&nbsp;<code>SELECT * FROM table_name WHERE id=@id<\/code><\/li><li><code>parameter_definition<\/code>&nbsp;is a string that contains the definition of all parameters embedded in the&nbsp;<code>sql_statement<\/code>. Each parameter definition consists of a parameter name and its data type e.g.,&nbsp;<code>@id INT<\/code>. The parameter definitions are separated by a comma (,).<\/li><li><code>@param1 = value1<\/code>,&nbsp;<code>@param2 = value2<\/code>,\u2026 specify a value for every parameter defined in the&nbsp;<code>parameter_definition<\/code>&nbsp;string.<\/li><\/ul>\n\n\n\n<p>This example uses the&nbsp;<code>sp_executesql<\/code>&nbsp;stored procedure to find products which have list price greater than 100 and category 1:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>12345678910111213<\/td><td>EXEC sp_executesqlN&#8217;SELECT *&nbsp;&nbsp;&nbsp;&nbsp;FROM &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;production.products &nbsp;&nbsp;&nbsp;&nbsp;WHERE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list_price&gt; @listPrice AND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;category_id = @categoryId&nbsp;&nbsp;&nbsp;&nbsp;ORDER BY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list_price DESC&#8217;, N&#8217;@listPrice DECIMAL(10,2),@categoryId INT&#8217;,@listPrice = 100,@categoryId = 1;<\/td><\/tr><\/tbody><\/table>\n","protected":false},"excerpt":{"rendered":"<p>Introduction to Dynamic SQL Dynamic SQL is a programming technique that allows you to construct SQL statements dynamically at runtime. It allows you to create more general purpose and flexible SQL statement because the full&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,18,19],"tags":[],"_links":{"self":[{"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/posts\/166"}],"collection":[{"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/comments?post=166"}],"version-history":[{"count":1,"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/posts\/166\/revisions"}],"predecessor-version":[{"id":167,"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/posts\/166\/revisions\/167"}],"wp:attachment":[{"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/media?parent=166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/categories?post=166"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/sumitjangid.com\/index.php\/wp-json\/wp\/v2\/tags?post=166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}