Question

The query is an insert into select statement where the parameters are generated from a csv file. The query fails because it cannot find the relationship between two of the tables. The table definition is as follows:

Users
----------
AgentID <PK>(Long Integer)
....

Chages
----------
ChangeID <PK>(Auto Number)
AgentID <FK>(Long Integer)
....

The relationship is between Users.AgentID = Changes.AgentID and the value being inserted into Changes can be found in Users.

The query is as follows:

    string sqlInsertChange = "INSERT INTO Changes" +
                                "(AgentID, ChangeReasonID, RecDateID, EffDateID) " +
                             "SELECT " +
                                "@AID AS AgentID, C.ChangeReasonID, " +
                                "(SELECT D.DateID FROM DateCodes AS D WHERE D.DateValue = @RD) AS RecDateID, " +
                                "(SELECT D.DateID FROM DateCodes AS D WHERE D.DateValue = @ED) AS EffDateID " +
                             "FROM " +
                                "ChangeReasons AS C " +
                             "WHERE " +
                                "C.ChangeReason = @CR;";



    UpdateChageCmd = new OleDbCommand(sqlInsertChange, conn);

    UpdateChageCmd.Parameters.Add("@AID", OleDbType.Integer);
    UpdateChageCmd.Parameters.Add("@RD", OleDbType.Date);
    UpdateChageCmd.Parameters.Add("@ED", OleDbType.Date);
    UpdateChageCmd.Parameters.Add("@CR", OleDbType.VarWChar);


    UpdateChageCmd.Parameters["@AID"].Value = chg.AgentID;
    UpdateChageCmd.Parameters["@RD"].Value = chg.recDate;
    UpdateChageCmd.Parameters["@ED"].Value = chg.effDate;
    UpdateChageCmd.Parameters["@CR"].Value = chg.reason;

    UpdateChageCmd.ExecuteNonQuery();

chg.AgentID is a long datatype.

I can put the query in Access, replacing the parameters with values, and it inserts without any problems.

Any ideas as to why this is not working?

EDIT: I hard-coded an AgentID value that I know is in the DB into the parameter but it still gave the error.

Was it helpful?

Solution

I was able to recreate your issue. It is very strange.

It seems that OleDb is getting confused by ... SELECT @AID AS AgentID .... Regardless of the value I gave to that Parameter (e.g., 1) it always got inserted into the database as 41641. When I tried to use .AddWithValue I got a "Data type mismatch" exception when I tried to execute the query.

This seems to work with OleDb, but it's a bit ugly:

string sqlInsertChange = 
        "INSERT INTO Changes" +
            "(AgentID, ChangeReasonID, RecDateID, EffDateID) " +
        "SELECT " +
            chg.AgentID + " AS AgentID, C.ChangeReasonID, " +
            "(SELECT D.DateID FROM DateCodes AS D WHERE D.DateValue = @RD) AS RecDateID, " +
            "(SELECT D.DateID FROM DateCodes AS D WHERE D.DateValue = @ED) AS EffDateID " +
        "FROM " +
            "ChangeReasons AS C " +
        "WHERE " +
            "C.ChangeReason = @CR;";

using (var UpdateChageCmd = new OleDbCommand(sqlInsertChange, conn))
{
    //UpdateChageCmd.Parameters.Add("@AID", OleDbType.Integer);
    UpdateChageCmd.Parameters.Add("@RD", OleDbType.Date);
    UpdateChageCmd.Parameters.Add("@ED", OleDbType.Date);
    UpdateChageCmd.Parameters.Add("@CR", OleDbType.VarWChar);

    //UpdateChageCmd.Parameters["@AID"].Value = chg.AgentID;
    UpdateChageCmd.Parameters["@RD"].Value = chg.recDate;
    UpdateChageCmd.Parameters["@ED"].Value = chg.effDate;
    UpdateChageCmd.Parameters["@CR"].Value = chg.reason;

    UpdateChageCmd.ExecuteNonQuery();
}

Or, if you're willing to switch from OleDb to Odbc then this works, too:

string sqlInsertChange = 
        "INSERT INTO Changes" +
            "(AgentID, ChangeReasonID, RecDateID, EffDateID) " +
        "SELECT " +
            "? AS AgentID, C.ChangeReasonID, " +
            "(SELECT D.DateID FROM DateCodes AS D WHERE D.DateValue = ?) AS RecDateID, " +
            "(SELECT D.DateID FROM DateCodes AS D WHERE D.DateValue = ?) AS EffDateID " +
        "FROM " +
            "ChangeReasons AS C " +
        "WHERE " +
            "C.ChangeReason = ?;";

using (var UpdateChageCmd = new OdbcCommand(sqlInsertChange, conn))
{
    UpdateChageCmd.Parameters.Add("?", OdbcType.Int);
    UpdateChageCmd.Parameters.Add("?", OdbcType.DateTime);
    UpdateChageCmd.Parameters.Add("?", OdbcType.DateTime);
    UpdateChageCmd.Parameters.Add("?", OdbcType.NVarChar);

    UpdateChageCmd.Parameters[0].Value = chg.AgentID;
    UpdateChageCmd.Parameters[1].Value = chg.recDate;
    UpdateChageCmd.Parameters[2].Value = chg.effDate;
    UpdateChageCmd.Parameters[3].Value = chg.reason;

    UpdateChageCmd.ExecuteNonQuery();
}

OTHER TIPS

According to http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbtype.aspx, an OleDbType.Integer is a 32 bit signed integer.

But a c# long, is a 64 big signed integer http://msdn.microsoft.com/en-us/library/ctetwysk.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top