まず第一に、このようなクライアントアプリで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)。しかし、ストアドプロシージャは、このような場合に、より管理しやすく、エラーが発生しにくいセキュリティ機能を提供すると思います。