简体   繁体   中英

C# Access: Data type mismatch in criteria expression error for INSERT SQL statement

I've checked other questions similar to this on this site but none of their solutions worked for me.

I am using SQL in C# to try and insert new records into a local Access database. Currently I am getting this error when it is run.

The full method:

public static void AddNewMusicFile(MusicFile m)
{
        long newID;
        int genreID = GenreDB.GetGenreID(m.AUDFIL_GENRE_NM);

        String strSQL = String.Empty;

        OleDbTransaction transaction = null;
        OleDbCommand cm = new OleDbCommand();
        OleDbConnection cn = new OleDbConnection(strConnString);

        cm.Connection = cn;

        cn.Open();

        transaction = cn.BeginTransaction();

        cm.Connection = cn;
        cm.Transaction = transaction;

        strSQL = "INSERT INTO AUDIOFILES_MSTR ";
        strSQL += "(";
        strSQL += "AUDFIL_TT, ";
        strSQL += "AUDFIL_RELEASE_DTM, ";
        strSQL += "AUDFIL_LENGTH, ";
        strSQL += "AUDFIL_GENRE_ID, ";
        strSQL += "AUDFIL_TYPE_ID, ";
        strSQL += "AUDFIL_ADD_DTM, ";
        strSQL += "AUDFIL_STAT_CD ";
        strSQL += ") VALUES (";
        strSQL += "@AUDFIL_TT, ";
        strSQL += "@AUDFIL_RELEASE_DTM, ";
        strSQL += "@AUDFIL_LENGTH, ";
        strSQL += "@AUDFIL_GENRE_ID, ";
        strSQL += "@AUDFIL_TYPE_ID, ";
        strSQL += "@AUDFIL_ADD_DTM, ";
        strSQL += "@AUDFIL_STAT_CD ";
        strSQL += ")";
        cm.CommandText = strSQL;

        OleDbParameter pm = new OleDbParameter("@AUDFIL_TT", OleDbType.Char, 163);
        pm.Direction = ParameterDirection.Input;
        pm.Value = m.AUDFIL_TT;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@AUDFIL_RELEASE_DTM", OleDbType.Date);
        pm.Direction = ParameterDirection.Input;
        pm.Value = m.AUDIL_RELEASE_DTM;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@AUDFIL_LENGTH", OleDbType.Integer);
        pm.Direction = ParameterDirection.Input;
        pm.Value = m.AUDFIL_LENGTH;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@genreID", OleDbType.Integer);
        pm.Direction = ParameterDirection.Input;
        pm.Value = genreID;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@AUDFIL_TYPE_ID", OleDbType.Integer);
        pm.Direction = ParameterDirection.Input;
        pm.Value = m.AUDFIL_TYPE_ID;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@AUDFIL_ADD_DTM", OleDbType.Date);
        pm.Direction = ParameterDirection.Input;
        pm.Value = m.AUDFIL_ADD_DTM;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@AUDFIL_STAT_CD", OleDbType.VarChar, 1);
        pm.Direction = ParameterDirection.Input;
        pm.Value = 'A';
        cm.Parameters.Add(pm);

        cm.ExecuteNonQuery();

        cm.CommandText = "SELECT @@IDENTITY AS AUDFIL_ID;";
        newID = int.Parse(cm.ExecuteScalar().ToString());

        strSQL = "INSERT INTO MUSICFILES_SPLM ";
        strSQL += "(";
        strSQL += "AUDFIL_ID, ";
        strSQL += "MSC_ARTIST_NM, ";
        strSQL += "MSC_ALBUM_NM, ";
        strSQL += "MSC_PRODUCER_NM, ";
        strSQL += "MSC_LABEL_NM ";
        strSQL += ") VALUES (";
        strSQL += "@AUDFIL_ID, ";
        strSQL += "@MSC_ARTIST_NM, ";
        strSQL += "@MSC_ALBUM_NM, ";
        strSQL += "@MSC_PRODUCER_NM, ";
        strSQL += "@MSC_LABEL_NM ";
        strSQL += ")";
        cm.CommandText = strSQL;

        pm = new OleDbParameter("@AUDFIL_ID", OleDbType.Integer);
        pm.Direction = ParameterDirection.Input;
        pm.Value = newID;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@MSC_ARTIST_NM", OleDbType.Char, 50);
        pm.Direction = ParameterDirection.Input;
        pm.Value = m.MSC_ARTIST_NM;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@MSC_ALBUM_NM", OleDbType.Char, 163);
        pm.Direction = ParameterDirection.Input;
        pm.Value = m.MSC_ALBUM_NM;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@MSC_PRODUCER_NM", OleDbType.Char, 50);
        pm.Direction = ParameterDirection.Input;
        pm.Value = m.MSC_PRODUCER_NM;
        cm.Parameters.Add(pm);

        pm = new OleDbParameter("@MSC_LABEL_NM", OleDbType.Char, 30);
        pm.Direction = ParameterDirection.Input;
        pm.Value = m.MSC_LABEL_NM;
        cm.Parameters.Add(pm);

        cm.ExecuteNonQuery();
        transaction.Commit();
}

The error is triggered at the last cm.ExecuteNonQuery() before the transaction is committed.

The table I am trying to add data into is this one:

Table Structure

The method that creates the music file object and calls on the add method:

private void btnAdd_Click(object sender, EventArgs e)
{
        MusicFile m = new MusicFile();
        m.MSC_ARTIST_NM = txtArtist.Text;
        m.MSC_ALBUM_NM = txtAlbum.Text;
        m.MSC_PRODUCER_NM = txtProducer.Text;
        m.MSC_LABEL_NM = txtLabel.Text;

        m.AUDFIL_TT = txtTitle.Text;
        m.AUDIL_RELEASE_DTM = dtpReleaseDate.Value;
        m.AUDFIL_TYPE_ID = 1;
        m.AUDFIL_LENGTH = (((long)nudHours.Value * 3600) + ((long)nudMinutes.Value * 60) + (long)nudSeconds.Value);
        m.AUDFIL_GENRE_NM = cbxGenre.SelectedItem.ToString();
        m.AUDFIL_ADD_DTM = Convert.ToDateTime(DateTime.Now.ToShortDateString());

        AudioBaseDB.AddNewMusicFile(m);
        MessageBox.Show("Record Added Successfully");
}

I have been stuck on this for a few hours now and cannot find which parameter is causing the error.

You are using the same command for three different executions. The problem is that you don't clear the parameters collection, so you end trying to insert the first set of parameters with the third execution

....
// First execution with the set of parameters defined before
cm.ExecuteNonQuery();

// Second execution, no parameters required here
cm.CommandText = "SELECT @@IDENTITY AS AUDFIL_ID;";
newID = int.Parse(cm.ExecuteScalar().ToString());

// Before starting to add the parameters for the final INSERT
// clear the collection from the previous ones
cm.Parameters.Clear();
....

In OleDb parameters are not recognized by their names, but by their positions.
Having added a first block of parameters related to the first INSERT means that OleDb will take the first parameter added to the collection (@AUDFIL_TT) as the value for the first parameter placeholder (@AUDFIL_ID) when it executes the final INSERT. Luckily, the data types don't match and you get an error message. If, by chance, all kinds of datatypes were right, you would have entered erroneous data in the second table.

A personal side note: Instead of concatenatig the command text in that way I prefer to use the verbatim string literal with the @ character.
I find it more readable.

strSQL = @"INSERT INTO AUDIOFILES_MSTR
             (AUDFIL_TT,AUDFIL_RELEASE_DTM,AUDFIL_LENGTH, 
              AUDFIL_GENRE_ID,AUDFIL_TYPE_ID,AUDFIL_ADD_DTM, 
              AUDFIL_STAT_CD) 
           VALUES 
             (@AUDFIL_TT,@AUDFIL_RELEASE_DTM,@AUDFIL_LENGTH,
              @AUDFIL_GENRE_ID, @AUDFIL_TYPE_ID, @AUDFIL_ADD_DTM,
              @AUDFIL_STAT_CD)";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM