11

OleDb を介して実行している SQL ステートメントがあります。ステートメントは次のようなものです。

INSERT INTO mytable (name, dept) VALUES (@name, @dept);

次のように OleDbCommand にパラメーターを追加しています。

OleDbCommand Command = new OleDbCommand();
Command.Connection = Connection;

OleDbParameter Parameter1 = new OleDbParameter();
Parameter1.OleDbType = OleDbType.VarChar;
Parameter1.ParamterName = "@name";
Parameter1.Value = "Bob";

OleDbParameter Parameter2 = new OleDbParameter();
Parameter2.OleDbType = OleDbType.VarChar;
Parameter2.ParamterName = "@dept";
Parameter2.Value = "ADept";

Command.Parameters.Add(Parameter1);
Command.Parameters.Add(Parameter2);

私が持っている問題は、逆にコマンドにパラメーターを追加すると、列に間違った値が入力されることです (つまり、名前は部門列にあり、その逆も同様です)。

Command.Parameters.Add(Parameter2);
Command.Parameters.Add(Parameter1);

私の質問は、パラメーター値がコマンドに追加された順序でテーブルに挿入された場合、パラメーター名のポイントは何ですか? パラメータ名が冗長に見えますか?

4

2 に答える 2

15

問題は、OleDb (および Odbc も) が名前付きパラメーターをサポートしていないことです。
位置パラメータと呼ばれるもののみをサポートします。

つまり、コマンド パラメータ リストに追加するときにパラメータに付ける名前は重要ではありません。OleDbCommand クラスによって内部的にのみ使用されるため、パラメーターを区別して参照できます。

重要なのは、パラメータをリストに追加する順序です。これは、疑問符文字 ( ?) を介して SQL ステートメントでパラメーターが参照される順序と同じである必要があります。

ただし、SQL ステートメントで名前付きパラメーターを使用できるようにするソリューションを次に示します。基本的に、SQL ステートメント内のすべてのパラメーター参照を疑問符に置き換え、それに応じてパラメーター リストを並べ替えます。OdbcCommand クラスでも同じように機能します。コード内で「OleDb」を「Odbc」に置き換えるだけです。

次のようなコードを使用します。

command.CommandText = "SELECT * FROM Contact WHERE FirstName = @FirstName";
command.Parameters.AddWithValue("@FirstName", "Mike");
command.ConvertNamedParametersToPositionalParameters();

そして、ここにコードがあります

public static class OleDbCommandExtensions
{
    public static void ConvertNamedParametersToPositionalParameters(this OleDbCommand command)
    {
        //1. Find all occurrences of parameter references in the SQL statement (such as @MyParameter).
        //2. Find the corresponding parameter in the commands parameters list.
        //3. Add the found parameter to the newParameters list and replace the parameter reference in the SQL with a question mark (?).
        //4. Replace the commands parameters list with the newParameters list.

        var newParameters = new List<OleDbParameter>();

        command.CommandText = Regex.Replace(command.CommandText, "(@\\w*)", match =>
        {
            var parameter = command.Parameters.OfType<OleDbParameter>().FirstOrDefault(a => a.ParameterName == match.Groups[1].Value);
            if (parameter != null)
            {
                var parameterIndex = newParameters.Count;

                var newParameter = command.CreateParameter();
                newParameter.OleDbType = parameter.OleDbType;
                newParameter.ParameterName = "@parameter" + parameterIndex.ToString();
                newParameter.Value = parameter.Value;

                newParameters.Add(newParameter);
            }

            return "?";
        });

        command.Parameters.Clear();
        command.Parameters.AddRange(newParameters.ToArray());
    }
}
于 2014-02-21T05:19:39.213 に答える
6

パラメータ NAMES は、SQL サポート システムでは一般的なものです (つまり、OleDb 固有ではありません)。ほとんどの場合、OleDb / Odbc のみがそれらを使用しません。それらが存在するのは、OleDb がジェネリック基本クラスの特定の実装であるためです。

于 2010-03-09T08:59:39.237 に答える