2012-09-04 218 views
-1

稱爲Emp的表包含id,name,lname,birthdate,address and salery。我想從emp中進行選擇。 基本查詢:select * from emp 如果爲lname傳遞值,查詢:select * from emp where lname = 'fgfg'像這樣。 所以我創建了以下sp。執行sp_executesql

create Procedure Proc_selectEmp 
(
@name varchar(10) = null, 
@lname varchar(10) = null, 
@id varchar(10) = null 

) 
as 
begin 

select * from Emp 
where 
(@name is null or name = @name) 
and (@lname is null or lname = @lname) 
and (@id is null or id = @id) 
end 

和emp一樣,有13個表具有相同的列名。 所以我tablenmae也dynamic.That就是爲什麼我選擇執行sp_executesql.Can我創建這樣

create Procedure Proc_selectEmp 
(
@name varchar(10) = null, 
@lname varchar(10) = null, 
@id varchar(10) = null 
@tableName varchar(30) 
) 
as 
begin 
declare @query nvarchar(1000) 
set @query = @query +'select * from '[email protected]+' 
where ('[email protected]+' is null or name = '[email protected]+') 
and ('[email protected]+' is null or lname = '[email protected]+') 
and ('[email protected]+' is null or id = '[email protected]+') 
end' 

execute sp_executesql @query 
+0

我找不到問題。你有問題嗎? – Steve

+0

如果問題是:「我可以動態構建SQL嗎?」那麼答案是「是」。 –

+2

但是閱讀SQL注入。並使用'QUOTENAME'。請參閱[動態SQL的詛咒和祝福 - 處理動態表和列名稱](http://www.sommarskog.se/dynamic_sql.html#objectnames) –

回答

-4

當然可以,但你必須寫

EXECUTE(@query)  

而不是

execute sp_executesql @query 
+2

不,您不需要。通常首選'sp_executesql',因爲您至少可以參數化一些部分。 –

+0

我很抱歉,但在他的情況下,他不需要它。執行對他的情況來說是完美的。 – Massanu

+1

您的措辭「*您必須寫*」「*」而不是*「......看起來好像您在說'sp_executesql'特別*不起作用*,這顯然是錯誤的。 –

1

它會工作,雖然它很臭,但它要求它要求表名是一個變量,因此表必須具有相同的列定義。

此外,而不是包括@param is null or column = @param,而是完全省略不必要的過濾器,這很容易做,因爲您正在使用動態sql。這將避免parameter sniffing problem

最後,不是將列過濾器附加到字符串中,而是使用sp_executesql的參數化重載,它將保護您免受SQL注入攻擊,並處理爲您引用的引號等。不幸的是,@tablename不能參數化,但希望?這不是用戶或外部提供的變量(在這種情況下,您需要對設計和驗證技術進行更多的思考)。

declare @query nvarchar(max) 
set @query = N'select * from ' + @tableName + N` where (1=1)` 

if (@name is not null) 
    set @query = @query + N'and name = @name' 

-- ... same for @id and @lname 

exec sp_executesql @SQL, 
    N'@name varchar(10), 
     @lname varchar(10), 
     @id varchar(10)', 
     @name = @name, 
     @lname = @lname, 
     @id = @id 

編輯 回覆:確保un-parameterizable輸入,比如在動態SQL表或列名 - see this post here的想法 - 用QUOTENAME和白名單列/表名是突出。