EXEC @Var
を使用する場合 (括弧なし - つまり、ではない EXEC (@Var)
) SQL Server は、@Var
で渡された名前に一致するストアド プロシージャを検索します。 .これには 3 部構成の命名法を使用できます。
sys.sp_executesql
の場合 は 3 部構成の名前で呼び出され、コンテキストはそれが呼び出されたデータベースに設定されます。
ゼロでこれを行うことができます SQL インジェクションのリスクは以下のとおりです。
CREATE PROCEDURE dbo.test @dbname SYSNAME, @col SYSNAMEAS SET NOCOUNT, XACT_ABORT ON; DECLARE @db_sp_executesql NVARCHAR(300) =QUOTENAME(@dbname) + '.sys.sp_executesql' EXEC @db_sp_executesql N' SELECT TOP 100 * FROM sys.columns WHERE name =@col', N'@col sysname', @col =@col コード> プレ>
上記が不可能であったとしても、動的 SQL をここのように安全な方法で使用することは完全に可能であると私は主張します.
CREATE PROCEDURE dbo.test @dbname SYSNAME, /*識別子に正しいデータ型を使用する*/ @col SYSNAMEAS SET NOCOUNT ON SET XACT_ABORT ON IF DB_ID(@dbname) IS NULL /*データベース名が存在することを確認する*/ BEGIN RAISERROR('無効なデータベース名が渡されました',16,1) RETURN ENDDECLARE @dynsql nvarchar(max) /*QUOTENAME を使用して特殊文字を正しくエスケープします*/SET @dynsql =N'USE '+ QUOTENAME(@dbname) + N ' SELECT TOP 100 * FROM sys.tables WHERE name =@col' /*sp_executesql を使用して WHERE 句をパラメータ化したままにする*/EXEC sp_executesql @dynsql, N'@col sysname', @col =@col
プレ>