2

MySQL Connector / Netを使用していて、実行時に名前が指定されるテーブルに対してクエリを作成したいと思います。

この例は私の頭のてっぺんから外れています(テストされていません):

public class DataAccess
{
    public enum LookupTable
    {
        Table1,
        Table2,
        Table3
    }

    public int GetLookupTableRowCount(LookupTable table)
    {
        string tableName = string.Empty;

        switch (table)
        {
            case LookupTable.Table1: 
                tableName = "table_1";
                break;
            case LookupTable.Table2: 
                tableName = "table_2";
                break;
            case LookupTable.Table3: 
                tableName = "table_3";
                break;
            default:
                throw new ApplicationException("Invalid lookup table specified.");
        }

        string commandText = string.Concat("SELECT COUNT(*) FROM ", tableName);

    // Query gets executed and function returns a value here...
    }
}

クエリでテーブル名をパラメータ化できるとは思わないので、 SQLインジェクションの可能性を制限するために、関数パラメータで文字列ではなく列挙型を使用しました。

それは良いアプローチのように思えますか?もっと良い方法はありますか?

4

3 に答える 3

4

MySQLでは識別子(テーブル名またはフィールド名)をパラメータ化することはできませんが、バッククォートを使用してそれらをエスケープすることはできます。

次のクエリは安全に実行されますが、テーブルが存在しないためエラーが発生します(奇妙な可能性がある場合を除いて、実際にこのような名前のテーブルがあります)。

SELECT * FROM `users; DROP TABLE users;`;

基本的に、動的な名前またはフィールドは、バッククォートで囲まれている限り使用できます。この方法でSQLインジェクションを防ぐには、最初にバッククォートを取り除くだけです。

tableName = tableName.Replace("`", "");
string commandText = "SELECT COUNT(*) FROM `" + tableName + "`";
于 2010-01-15T19:21:33.597 に答える
2

動的テーブル名は決して良いアプローチではありません(PHPMyAdminまたは類似のものを開発している場合を除きます)。

テーブル名が限られている場合は、ストアドプロシージャを作成し、パラメータを使用して呼び出してみませんか?

DECLARE _which INT
BEGIN
        SELECT  COUNT(*)
        FROM    table_1
        WHERE    _which = 1
        UNION ALL
        SELECT  COUNT(*)
        FROM    table_2
        WHERE    _which = 2
        UNION ALL
        SELECT  COUNT(*)
        FROM    table_3
        WHERE   _which = 3
END
于 2010-01-15T19:22:31.220 に答える
1

そうです、テーブル名、列名、SQLキーワードまたは式などにクエリパラメータを使用することはできません。クエリパラメータは単一の値にのみ使用できます。

入力からリテラルテーブル名へのある種のマッピングを行うことが、SQLインジェクションから保護するための良い方法であることに同意します。

私は.NETでプログラミングしていません。通常、PHP、Python、Perlなどの動的言語を使用しています。だから私はハッシュ配列を使います。switch()列挙型変数を使用してハッシュ配列にインデックスを付けることができる場合は、スキップできます。

$tableName = $tableNameHash[ $table ];

.NETはハッシュマップタイプのデータ構造をサポートしていますか?それが私が探しているものです。


hash_map標準C++ライブラリにクラスがあるようです。

于 2010-01-15T19:19:27.097 に答える