-1

Emp というテーブルが含まれていid,name,lname,birthdate,address and saleryます。emp から選択したいです。基本クエリ : select * from emp lname ,query の値を渡す場合:select * from emp where lname = 'fgfg'このように。そこで、次のspを作成しました。

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も動的です。そのため、execute sp_executesqlを選択します。このように作成できますか

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 '+@tableName+'
where ('+@name+' is null or name = '+@name+') 
and ('+@lname+' is null or lname = '+@lname+') 
and ('+@id+' is null or id = '+@id+')
end'

execute sp_executesql @query
4

2 に答える 2

1

テーブル名が変数である必要があり、テーブルに同じ列定義が必要であることを考えると、かなり臭いですが、機能します。

また、を含めるの@param is null or column = @paramではなく、不要なフィルターを完全に除外します。これは、動的 SQL を使用しているため簡単です。これにより、パラメータ スニッフィングの問題が回避されます。

最後に、列フィルターを文字列に追加する代わりに、sp_executesqlSQL インジェクション攻撃から保護し、引用符などのエスケープを処理する のパラメーター化されたオーバーロードを使用します。残念ながら、@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でテーブル名や列名などの入力を 保護する-アイデア については、この投稿を参照してくださいQUOTENAME-列/テーブル名の使用とホワイトリスト化が目立ちます。

于 2012-09-04T08:14:57.367 に答える
-4

はい、できますが、書く必要があります

EXECUTE(@query)    

それ以外の

execute sp_executesql @query
于 2012-09-04T08:13:19.707 に答える