Search code examples
c#insertdbfoledbexception

How to insert into already existing DBF file?


I'm having trouble with insert command into already existing DBF File. My variable fullPath = "C:\Kasa_NMP\MAT_DAY.dbf"...

After I run this I get:

An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll

Additional information: Syntax error in INSERT INTO statement.

When I try to put ' ' around my fullPath variable I get:

An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll

Additional information: Syntax error in query. Incomplete query clause.

public static void DataTableToDBF(string filePath, string fileName, DataTable dataTable)
{
    string fullPath = filePath + fileName + ".dbf";

        using (OleDbConnection con = new OleDbConnection(GetConnection(filePath)))
        {
            con.Open();
            OleDbCommand cmd = new OleDbCommand();
            cmd.Connection = con;

            foreach (DataRow row in dataTable.Rows) // Insert redaka u DBF file
            {
                string insertCommand = "INSERT INTO " + fullPath + "(datum1, faktura, sifra_dob, sifra, naziv_art, ulaz, izlaz," + 
                    " jed_cijena, duguje, potrazuje, tarifa, rabat, n, pla, op, nab_cijena, porez_pr, sif_kup, time)" +
                " VALUES(@datum, @faktura, @sifra_dob, @sifra, @naziv_art, @ulaz, @izlaz, @jed_cijena, @duguje, @potrazuje," + 
                " @tarifa, @rabat, @n, @pla, @op, @nab_cijena, @porez_pr, @sif_kup, @time)";

                cmd.Parameters.AddWithValue("@datum", DateTime.Parse(row["Datum_k"].ToString()).ToShortDateString());
                cmd.Parameters.AddWithValue("@faktura", row["Dokument"]);
                cmd.Parameters.AddWithValue("@sifra_dob", row["BarKod"]);
                cmd.Parameters.AddWithValue("@sifra", row["Sifra"]);
                cmd.Parameters.AddWithValue("@naziv_art", row["NazivArtikla"]);
                cmd.Parameters.AddWithValue("@ulaz", row["Ulaz"]);
                cmd.Parameters.AddWithValue("@izlaz", row["Izlaz"]);
                cmd.Parameters.AddWithValue("@jed_cijena", row["Cijena"]);
                cmd.Parameters.AddWithValue("@duguje", row["Duguje"]);
                cmd.Parameters.AddWithValue("@potrazuje", row["Potrazuje"]);
                cmd.Parameters.AddWithValue("@tarifa", row["Tarifa"]);
                cmd.Parameters.AddWithValue("@rabat", row["Rabat"]);
                cmd.Parameters.AddWithValue("@n", 0);
                cmd.Parameters.AddWithValue("@pla", row["Placanje"]);
                cmd.Parameters.AddWithValue("@op", row["Operator"]);
                cmd.Parameters.AddWithValue("@nab_cijena", row["NabavnaCijena"]);
                cmd.Parameters.AddWithValue("@porez_pr", row["Porez"]);
                cmd.Parameters.AddWithValue("@sif_kup", row["SifraKomitenta"]);
                cmd.Parameters.AddWithValue("@time", row["Vrijeme"]);

                cmd.CommandText = insertCommand;
                cmd.ExecuteNonQuery();
            }
            con.Close();
    }
}

private static string GetConnection(string path)
{
    return "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + ";Extended Properties=dBASE IV;";
}

Solution

  • I can't find a precise documentation about reserved keywords for a DBF database system but the word TIME is highly suspected to be a reserved keyword.
    If this is true then you will receive the mentioned exception with a SYNTAX ERROR.

    The solution is always the same:

    • A) Try to use a different name for that column.
    • B) If A is not possible then enclose the TIME inside square brackets as ..., sif_kup, [time])"

    However you have other problems in your code. You are adding the parameters inside the loop. This means that at the second loop you have doubled the parameters collection, but what is worse is the position of these parameters. Because OleDb recognizes parameter according to their position in the collection, you will end writing the same values at each loop ignoring the other parameters.
    In this case I would set the commandtext and create the parameters outside the loop leaving them blank. Inside the loop I would change their values before executing the query.

    Or you can simply write

    cmd.Parameters.Clear(); 
    

    inside the loop before adding the parameters again and again at each loop.