1

私は、ユーザーが MS Access テーブルを選択して、それを特定の宛先の .csv ファイルにエクスポートできるようにするプログラムに取り組んでいます。問題は、選択したテーブルに sql 特殊文字が含まれているとエラーが発生することです。

このトピックについていくつかの調査を行いましたが、パラメーターを使用する必要があることは理解していますが、実際に使用する方法がわかりません。これが私のコードサンプルです:

        string destination = Form2.destination;
        string selectString = "SELECT * FROM " + tablename;                      
        string path = destination + "\\" + tablename + ".csv"; 
        File.Create(path).Dispose();
        TextWriter tw = new StreamWriter(path);

        OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtDataPath.Text);
        connection.Open();
        DataSet myDataSet = new DataSet();

        OleDbCommand command = new OleDbCommand(selectString,connection);

        OleDbDataAdapter adapter = new OleDbDataAdapter(command.CommandText,connection);
        adapter.Fill(myDataSet, tablename);

これまでのところ、特殊文字を含まないテーブル名が選択された場合、csv ファイルが作成されて見栄えがよくなりますが、「-」のようなものが含まれている場合、私のプログラムは「FROM 句の構文エラー」を生成します。特殊文字のためです。

私がこれまでに見た例のどれも、私がやろうとしていることで具体的に機能するとは思わないので、誰かが私を助けてくれることを願っています. ありがとう。

4

5 に答える 5

4

WHERE 条件または INSERT/UPDATE ステートメントの値を指定するために使用できますが、テーブルの名前または列の名前を置き換えることはできないため、実際のクエリにはパラメーターは必要ありません。

ただし、テーブル名に特殊文字 (スペースなど) が含まれている場合、テーブル名自体に問題があります
。この問題を回避するには、テーブル名を角括弧で囲みます。

string selectString = "SELECT * FROM [" + tablename + "]";

この方法で文字列を結合することは非常に危険であることを覚えておいてください。tablename 変数が適切にチェックされていないユーザー入力からのものである場合、SQL インジェクション攻撃のリスクがあります。

また、文字列の連結を使用してパスを作成しないでください。これには非常に便利なクラスがあります。

string path = Path.Combine(destination, tablename + ".csv"); 

最後に、Using ステートメントを使用して、接続やその他の使い捨てオブジェクトを囲むようにしてください。そうしないと、プログラムの安定性の問題になる可能性があるこれらのオブジェクトを適切に閉じて破棄することが保証されるからです。

using(OleDbConnection connection = new OleDbConnection("........"))
using(OleDbCommand command = new OleDbCommand(selectString,connection))
using(OleDbDataAdapter adapter = new OleDbDataAdapter(command))
{
    connection.Open();
    DataSet myDataSet = new DataSet();
    adapter.Fill(myDataSet, tablename);
}
于 2013-05-24T20:40:21.583 に答える
2

テーブル名を括弧で囲みます。以下は有効なコマンドです。

SELECT foo FROM [Le Tablé]

特殊文字を含まないテーブル名にも括弧を追加できるので、とにかくそれらをすべて囲んで満足してください。

于 2013-05-24T20:40:42.160 に答える
1

テーブル名を括弧で囲んでみてください。

SELECT * FROM [Some Table Name]
于 2013-05-24T20:39:54.373 に答える
1

まず、テーブル名を次のように括弧で囲みます。

string selectString = "SELECT * FROM [" + tablename + "]";

次に、クエリを次のようにパラメータ化します。

command.Parameters.Add("@parametername1here", OleDbType.VarChar).value = "somevalue"
command.Parameters.Add("@parametername2here", OleDbType.VarChar).value = "someothervalue"
于 2013-05-24T20:42:05.370 に答える
0

私が見る限り、あなたには 2 つの選択肢があります。

最初の簡単なオプションは、テーブル名をサニタイズすることです。

tableName = tableName.replace("-", "\\-");

ここでは適切ではないかもしれない 2 番目のオプションは、C# がSqlParameterインスタンスを使用して名前を自動的にエスケープできるようにすることです。(疑似コード) のようなもの:

    string selectString = "SELECT * FROM @tableName";                      
    // [...]
    OleDbCommand command = new OleDbCommand(selectString, connection);
    command.AddParameter(new SqlParamter("@tableName", tablename); // auto-escapes
于 2013-05-24T20:41:14.587 に答える