まず第一に、あなたは決してすべきではありません このようなクライアントアプリでSQLコマンドの作成を行います。それは SQLインジェクションとは何ですか。 (独自の特権を持たない管理ツールでは問題ありませんが、共有使用アプリケーションでは問題ありません)。
第二に、はい、ストアドプロシージャへのパラメータ化された呼び出しは、よりクリーンで安全です。
ただし 、これを行うには動的SQLを使用する必要があるため、実行されたクエリのテキストに渡された文字列を含めたくありません。代わりに、渡された文字列を使用して、実際のの名前を検索します。 ユーザーがその方法でクエリを実行できるようにする必要があるテーブル。
簡単な単純な例を次に示します。
CREATE PROC spCountAnyTableRows( @PassedTableName as NVarchar(255) ) AS
-- Counts the number of rows from any non-system Table, *SAFELY*
BEGIN
DECLARE @ActualTableName AS NVarchar(255)
SELECT @ActualTableName = QUOTENAME( TABLE_NAME )
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = @PassedTableName
DECLARE @sql AS NVARCHAR(MAX)
SELECT @sql = 'SELECT COUNT(*) FROM ' + @ActualTableName + ';'
EXEC(@SQL)
END
なぜこれがより安全なのかとかなり質問する人もいます。うまくいけば、小さなボビーテーブルがこれをより明確にすることができます:0
その他の質問への回答:
-
QUOTENAMEだけでは安全が保証されません。 MSは私たちにそれを使用することを勧めていますが、ハッカーにだまされないという保証はありません。参考までに、本当のセキュリティは保証がすべてです。 QUOTENAMEを使用したテーブルルックアップは別の話であり、壊れることはありません。
-
この例ではQUOTENAMEは厳密には必要ありません。通常、INFORMATION_SCHEMAでのルックアップ変換だけで十分です。 QUOTENAMEは、完全で正しいソリューションを含めることがセキュリティの良い形式であるため、ここにあります。ここにあるQUOTENAMEは、実際には、潜在的な注入として知られている、明確ではあるが同様の潜在的な問題から保護しています。 。
動的な列名とINFORMATION_SCHEMA.COLUMNS
でも同じことができることに注意してください。 テーブル。
代わりに、パラメーター化されたSQLクエリを使用して、ストアドプロシージャの必要性を回避することもできます(https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=を参照)。 netframework-4.8)。しかし、ストアドプロシージャは、このような場合に、より管理しやすく、エラーが発生しにくいセキュリティ機能を提供すると思います。