0

BG 情報:初心者テキスト ファイルの列から値を読み取り、それらを解析するデスクトップ アプリケーションの作成。テキストファイルのすべての値を 3 つのリスト (各リストはファイルのセクションを表すため、3 つのリスト) に格納することができました。これらのリスト値を sqlite db にロードする予定です。ここで問題が発生します。

エラー メッセージ: リストの値を転送しようとすると、コードの sqlite 部分で"near "[i]" 構文エラー"が発生します。具体的に言えば、この部分(以下のコードセグメントの3番目の部分として位置しています)

 sqlite_cmd.CommandText = "INSERT INTO table1 (Seq, Field, Description) VALUES (list[i], list[i+1], list[i+2]);"; 

重要な部分に至るまでのコード: (これは重要ではありません。必要な人が必要とする bg 情報のためにそこにあるだけです。以下の重要なコード セグメントを強調表示しています)

 namespace WindowsFormsApplication1

public partial class Form1 : Form
{
    string[] val = new string[10];
    string[] val2 = new string[6];
    string[] val3 = new string[7];
    string[] values = new string[1000];
    List<string> list = new List<string>();
    List<string> list2 = new List<string>();
    List<string> list3 = new List<string>();


    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        // Reading/Inputing column values



        OpenFileDialog ofd = new OpenFileDialog();
        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {

            // Data Reading from section 1.

            /*string[] lines = File.ReadAllLines(ofd.FileName).Skip(8).ToArray();
            textBox1.Lines = lines;
            */

            string[] fileLines = File.ReadAllLines(ofd.FileName);

            // Import table values from Section 1: from Seq# to YYYY-MM

            string[] section1 = fileLines.SkipWhile(line => !line.Contains("Seq#")).TakeWhile(line => !line.Contains("Total Records")).Where(line => Regex.IsMatch(line, @"[\s|\d]{4}\d")).Select(line => line.PadRight(198)).ToArray();


            int[] pos = new int[10] { 0, 6, 18, 47, 53,57, 61, 68, 82, 97 }; //setlen&pos to read specific colmn vals
            int[] len = new int[10] { 6, 12, 29, 6 , 4, 4, 7, 14, 15, 6 }; // only doing 3 columns right now

リストに列の値を入力するだけです:(この部分は正常に動作します)

            foreach (string line in section1)
            {
                //if (line.StartsWith("0")) break; 


                for (int j = 0; j < 10; j++) // 3 columns
                {
                    val[j] = line.Substring(pos[j], len[j]).Trim(); // each column value in row add to array
                    list.Add(val[j]); // column values stored in list

                }

            }

重要な部分: SQLite 接続 (ここでエラーが発生します)**

private void button4_Click(object sender, EventArgs e)
    {

        // [snip] - As C# is purely object-oriented the following lines must be put into a class:

        // We use these three SQLite objects:
        SQLiteConnection sqlite_conn;
        SQLiteCommand sqlite_cmd;


        // create a new database connection:
        sqlite_conn = new SQLiteConnection("Data Source=database.db;Version=3;New=True;Compress=True;");

        // open the connection:
        sqlite_conn.Open();

        // create a new SQL command:
        sqlite_cmd = sqlite_conn.CreateCommand();

        // Let the SQLiteCommand object know our SQL-Query:
        sqlite_cmd.CommandText = "CREATE TABLE table1 (Seq integer primary key, Field integer , Description integer );";

        // Now lets execute the SQL ;D                                                                                  
        sqlite_cmd.ExecuteNonQuery();

        for (int i = 0; i < 500; i+=3)
        {
            // Lets insert something into our new table:
            sqlite_cmd.CommandText = "INSERT INTO table1 (Seq, Field, Description) VALUES (list[i], list[i+1], list[i+2]);"; THIS IS WHERE PROBLEM OCCURS!

            // And execute this again ;D
            sqlite_cmd.ExecuteNonQuery(); 
        }

        // We are ready, now lets cleanup and close our connection:
        sqlite_conn.Close();
    }
4

1 に答える 1

4

変数を sql 文字列内に埋め込んで渡すことはできません。
このようにして、それらはリテラルになり、整数フィールドの値として機能できなくなります。
パラメータ化されたクエリを使用する必要があります

sqlite_cmd.CommandText = "INSERT INTO table1 (Seq, Field, Description) VALUES (@p1, @p2, @p3)";
sqlite_cmd.Parameters.AddWithValue("@p1", 0);  // dummy initial values 
sqlite_cmd.Parameters.AddWithValue("@p2", 0);
sqlite_cmd.Parameters.AddWithValue("@p3", 0);
for (int i = 0; i < 500; i+=3)
{
    sqlite_cmd.Parameters["@p1"].Value = Convert.ToInt32(list[i]);
    sqlite_cmd.Parameters["@p2"].Value = Convert.ToInt32(list[i+1]);
    sqlite_cmd.Parameters["@p3"].Value = Convert.ToInt32(list[i+2]); // Description as Integer ??
    sqlite_cmd.ExecuteNonQuery(); 
}

このコードでは、プレースホルダー @p1、@p2、および @p3 は、ループ内で適切な値に置き換えられるパラメーターを表します。ループに入る前に、コマンド パラメーター コレクションは、3 つのプレースホルダーに対応する 3 つのパラメーターとダミーの初期値で初期化されます。ループ内では、すべてのパラメーターがリスト変数から挿入する実際の値を受け取ります。

上記のコードには他の問題があります。

for (int j = 0; j < 10; j++) // 3 columns

9 ではなく 10 項目のこの行ループ (0 から 9 は 10 要素です)

データベースに値を挿入するためのパラメーターを供給するために使用される変数listに、整数ではなく文字列が含まれています。ただし、テーブルを作成するコードは、整数データ型の 3 つの列を定義します。Descriptionこれらの列の 1 つがほとんど数値と呼ばれていないため、これらの列にどのデータを格納しているかは明確ではありません。

編集あなたのコメントから、かなり古いバージョンの sqlite プロバイダーを使用しているようです。
この場合、パラメータを作成してコレクションに追加する必要があります。

sqlite_cmd.Parameters.Add(new SQLiteParameter("@p1", SqlDbType.Integer));
于 2013-10-29T21:02:24.343 に答える