儘管我一般建議不要使用動態sql,在這種情況下,我認爲你可以通過檢查@Table變量是否包含有效的表名來避開它。
- 的問題是,如果你打算允許模式名稱和/或跨數據庫查詢,我假設你不想出去的DB(或服務器)的在這裏,但也允許不同模式的(AdventureWorks顯示如何使用它們)
- 您可能還想包含@Table的視圖。
- 如果您還檢查了發現的對象是否實際上有ID列,並且如果不是,則拋出'userfriendly'錯誤,這可能是'很好'。儘管如此。
只要將QuoteName()放在@table周圍就不會保護你免受一切侵害。雖然功能很棒,但它還遠沒有完美。恕我直言,你最好的選擇是解析@Table變量,檢查它的內容是否有效,然後根據獲得的部分創建動態sql。 我開始做的最上方和令人驚訝的還有它需要檢查的東西看起來如此簡單的手=)
CREATE PROCEDURE [dbo].[GetDataByID] (
@ID bigint,
@Table nvarchar(300)
)
AS
DECLARE @sql nvarchar(max)
DECLARE @server_name sysname,
@db_name sysname,
@schema_name sysname,
@object_name sysname,
@schema_id int
SELECT @server_name = ParseName(@Table, 4),
@db_name = ParseName(@Table, 3),
@schema_name = ParseName(@Table, 2),
@object_name = ParseName(@Table, 1)
IF ISNULL(@server_name, @@SERVERNAME) <> @@SERVERNAME
BEGIN
RaisError('Queries are restricted to this server only.', 16, 1)
Return(-1)
END
IF ISNULL(@db_name, DB_Name()) <> DB_Name()
BEGIN
RaisError('Queries are restricted to this database only.', 16, 1)
Return(-1)
END
IF @schema_name IS NULL
BEGIN
IF NOT EXISTS (SELECT *
FROM sys.objects
WHERE name = @object_name
AND type IN ('U', 'V'))
BEGIN
RaisError('Requested @Table not found. [%s]', 16, 1, @object_name)
Return(-1)
END
SELECT @sql = 'SELECT * FROM ' + QuoteName(@object_name) + ' WHERE ID = @ID'
END
ELSE
BEGIN
SELECT @schema_id = Schema_id(@schema_name)
IF @schema_id IS NULL
BEGIN
RaisError('Unrecognized schema requested [%s].', 16, 1, @schema_name)
Return(-1)
END
IF NOT EXISTS (SELECT *
FROM sys.objects
WHERE name = @object_name
AND schema_id = @schema_id
AND type IN ('U', 'V'))
BEGIN
RaisError('Requested @Table not found. [%s].[%s]', 16, 1, @schema_name, @object_name)
Return(-1)
END
SELECT @sql = 'SELECT * FROM ' + QuoteName(@schema_name) + '.' + QuoteName(@object_name) + ' WHERE ID = @ID'
END
EXEC sp_executesql @stmt = @sql,
@params = N'@ID bigint',
@ID = @ID
Return(0)
同前編譯,但您可能需要以消除一些錯誤,因爲我沒」檢查所有的代碼路徑就行了。
只是一個不會影響很多東西的小東西,但是不是'@ Table'參數是這裏的問題嗎? '@ ID'是一個'bigint',所以當你到達構建動態SQL語句的位置時它只能是一個數字,對吧? – 2011-12-19 19:52:48
我想都是.. – 2011-12-19 19:54:24