1. 程式人生 > 實用技巧 >在SQL Server中執行動態SQL命令

在SQL Server中執行動態SQL命令

問題

在某些應用程式中,由於對資料庫伺服器發出查詢的動態特性,因此採用硬編碼的SQL語句並不吸引人。因此,有時需要動態地動態建立SQL語句,然後執行該命令。這可以從應用程式的角度非常簡單地完成,無論您使用的是ASP.NET,ColdFusion還是任何其他程式語言,都可以即時構建SQL語句。但是,如何從SQL Server儲存過程中執行此操作?

如何在SQL Server中構建動態SQL語句

SQL Server提供了幾種執行動態構建的SQL語句的方法。以下是一些選擇:

  1. 用引數編寫查詢
  2. 使用EXEC
  3. 使用sp_executesql

注意事項

儘管動態生成SQL程式碼是動態構建語句的一種簡便方法,但確實存在一些缺點。

一個問題是SQL注入的潛在可能性,其中惡意程式碼被插入到正在構建的命令中。下面的示例很容易上手,但是您應該瞭解SQL注入以及通過確保程式碼在執行正在生成的語句之前可以檢查任何問題的健壯性來防止它的方法。

另一個問題是動態生成程式碼可能會導致效能問題。您實際上並不知道使用者如何使用程式碼,因此查詢可能會執行您未曾期望的事情,從而成為效能問題。因此,請再次確保在執行生成的程式碼之前,您的程式碼檢查所有潛在的問題。

通過編寫帶有引數的查詢來實現動態SQL

如果只需要將引數傳遞到SQL語句的WHERE子句中,則第一種方法非常簡單。假設我們需要從客戶表中查詢所有記錄,其中City ='London'。

如下面的示例所示,這很容易做到。

DECLARE @city varchar(75)

SET @city = 'London'

SELECT * FROM Person.Address WHERE City = @city

我們可以將上述內容轉換為儲存過程,如下所示:

CREATE PROCEDURE dbo.uspGetCustomers @city varchar(75)
AS
BEGIN
   SELECT * FROM Person.Address WHERE City = @city
END
GO

然後可以執行以下操作:

dbo.uspGetCustomers @city = '
London'

使用EXEC的動態SQL命令

使用這種方法,您可以即時構建SQL語句,並且幾乎可以做任何需要構造該語句的事情。假設我們希望能夠將列列表與城市一起傳遞。

在此示例中,我們要獲取AddressID,AddressLine1和City列,其中City ='London'。

從該示例中可以看到,處理@city值並非一帆風順,因為您還需要定義額外的引號才能將字元值傳遞到查詢中。這些額外的引號也可以在語句中完成,但是無論哪種方式,您都需要指定額外的單引號,以便正確構建查詢並因此執行。

DECLARE @sqlCommand varchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)

SET @columnList = 'AddressID, AddressLine1, City'
SET @city = '''London'''
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM Person.Address WHERE City = ' + @city

EXEC (@sqlCommand)

使用sp_executesql的動態SQL命令

使用這種方法,您仍然可以動態地構建查詢,但是您也可以像示例1中那樣使用引數。這省去了必須處理多餘的引號才能正確構建查詢的需要。此外,使用這種方法可以確保傳遞到查詢中的資料值是正確的資料型別。

DECLARE @sqlCommand nvarchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)

SET @columnList = 'AddressID, AddressLine1, City'
SET @city = 'London'
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM Person.Address WHERE City = @city'

EXECUTE sp_executesql @sqlCommand, N'@city nvarchar(75)', @city = @city

因此,這是編寫動態查詢的三種不同方式。除了上述內容以外,這裡還有一些其他文章,它們為您提供了有關設定和使用動態SQL的其他觀點。