私が考えることができる最良の方法は2つの部分です。
名前をパラメーターとして受け取るストアード・プロシージャーがあります。このprocは、最初にカタログ(Information_Schema.Table
)でテーブル名を検索し、適切な名前を取得して、それが有効であることを確認します。
次に、このルックアップを使用して、ストアドプロシージャは、パラメータからではなく、必要なSQLを構築します。
このルックアップを使用すると、基本的に、無効なテーブル名が渡されるのを防ぐことができます。
CREATE PROCEDURE RunSQL
(@table NVARCHAR(50))
AS
BEGIN
DECLARE @validTableName NVARCHAR(50)
SELECT
@validTableName = TABLE_NAME
FROM
INFORMATION_SCHEMA.TABLES
WHERE
TABLE_NAME = @table
AND SCHEMA_NAME = 'dbo' -- here you can limit or customise the schema
IF @validTableName IS NULL
RAISE ... raise an exception
DECLARE @dynamicSql NVARCHAR(100) = REPLACE('SELECT * FROM dbo.[#TABLE#]', '#TABLE' @validTableName)
EXECUTE sp_executesql .... @dynamicSql ....
END
これを拡張して、検証、スキーマ、列などを使用できます。
最終的には、独自のSQLを構築し、インジェクションに対する保護を行う必要があります。それを回避することはできません。