C# ADO 参数化更新查询由于 DBNull 而无法更新

问题描述 投票:0回答:1

我花了一整天的时间来解决这个问题,但似乎找不到解决方案。我将参数 @dMCA 和 @dMOCP 添加到已经运行的更新查询中。这些值可以为空,因此我对其进行测试,如果它们实际上为空,则写入 DBnull。自从添加这些之后,查询就不再起作用了。查询不会通过“catch”出错。 这很奇怪,因为我对 @cirID 没有任何问题,它的值也可以为空。

我看到的每个人,包括人工智能工具,都说我做的事情是正确的。

我该如何解决这个问题。我不知道从这里去哪里?这是我的第一个 .Net 程序。在认为这个项目已经完成几个月后,我发现这个更新查询不起作用。现在我处于恐慌模式,不知道我是否可以相信我的任何查询。如果他们没有抛出错误并落入“陷阱”,我该如何捕获这样的设计缺陷。

请帮助我学习。谢谢大家。

没有效果的SQL更新:

        static void UpdateDM_Equip(DMMotor motor, string DBLocation)
    {
        var conString = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source = " + DBLocation;
        var SQLString = "UPDATE tblEquL set EQU_CALLOUT = @name, ixCircuit1 = @cirID, LT_CON_1 = @KVA, LT_HP_1 = @HP, LT_CAL_1 = @NEC , LT_FAC_1 = @factor , D_NOTE = @note1, R_NOTE = @note2, dMCA = @MCA, dMOCP = @MOCP WHERE ixEquL = @ID";
        using (OleDbConnection connection = new OleDbConnection(conString)) //create a connection
        {
            OleDbCommand cmd = new OleDbCommand(SQLString, connection); //create a command and set its connection
            try
            {
                connection.Open(); //open connection
                cmd.Parameters.AddWithValue("@name", motor.EQU_CALLOUT); //add the safe parameter
                cmd.Parameters.AddWithValue("@cirID", motor.ixCircuit1.HasValue ? motor.ixCircuit1.Value : DBNull.Value); //add the safe parameter
                cmd.Parameters.AddWithValue("@KVA", motor.LT_CON_1); //add the safe parameter
                cmd.Parameters.AddWithValue("@HP", motor.LT_HP_1); //add the safe parameter
                cmd.Parameters.AddWithValue("@NEC", motor.LT_CAL_1); //add the safe parameter
                cmd.Parameters.AddWithValue("@factor", motor.LT_FAC_1); //add the safe parameter
                cmd.Parameters.AddWithValue("@note1", motor.D_NOTE); //add the safe parameter
                cmd.Parameters.AddWithValue("@note2", motor.R_NOTE); //add the safe parameter
                cmd.Parameters.AddWithValue("@ID", motor.ixEquL); //add the safe parameter
                cmd.Parameters.AddWithValue("@MCA", motor.dMCA.HasValue ? motor.dMCA.Value : DBNull.Value); //add the safe parameter
                cmd.Parameters.AddWithValue("@MOCP", motor.dMOCP.HasValue ? motor.dMOCP.Value : DBNull.Value); //add the safe parameter
                cmd.ExecuteNonQuery();
                Debug.WriteLine("Command Text: " + cmd.CommandText);
            }//end of try
            catch (Exception ex)
            {
                Debug.WriteLine("UpdateDM_Equip error: " + ex.Message);
                foreach (OleDbParameter parameter in cmd.Parameters)
                {
                    Debug.WriteLine(parameter.ParameterName + ": " + (parameter.Value ?? "NULL"));
                }
            } //end of catch
        }//end of using. Automatically closes connections
    }

SQL更新中使用的类定义(仅供参考):

    class DMMotor
{
    //init fields/members - TODO review how we are handling several of these fields that determine load type and thus NEC demand factor.
    public int ixEquL; //Access table primary Key
    public string EQU_CALLOUT = "";
    public string Distribution_Equip; //Non-DM variable. Custom for processing conversion of other motor types
    public double bucketSpace = 1; //NON-DM variable. Custom for calcing how much of MMC section motor needs.
    public int Circuit_ID_TEI_DB; //NON-DM variable. Custom temp store the TEI database circuit_ID (primary Key). Used to determine if equip shares circuit per TEI DB V21C+ assignment.
    public double Circuit_KVA_con_TEI_DB; //NON-DM variable. Custom temp store TEI DB circuits connected KVA
    public double Circuit_FLA_con_TEI_DB; //NON-DM variable. Custom temp store TEI DB circuits connected FLA
    public double Circuit_KVA_op_TEI_DB; //NON-DM variable. Custom temp store TEI DB circuits Operating KVA
    public int iID = 0;
    public int? ixCircuit1; //holds the circuit assignment relation - Could be null
    public int ixEquSGroup;
    public int ixDwgEqu;
    public int iCircuitPhase = 1; //default value when you manually create equipment without dist assign.
    public int ixLayerSystem = 1;
    public int iBreakerSize = 3; //cloest field to determining Phase. 2nd closest is V_P_W. I will use this in UpdateDM_Circuit
    public int? BreakerKey; //NON_DM variable. Custom field to store the tblbreaker key for a breaker size that is read in from tbl Electrical_Circuits
    public int BreakerAmps; //NON_DM variable. Custom field to store breaker size in amps before determing the breaker key and populating DMMotor.BreakerKey
    public int iBreakerWire = 1;
    public bool bInsertedOnDrawing = false;
    public bool bShowOnOneLine = true; //bool to show on SL
    public bool bShowInSchedule = true;
    public bool bShowFeederID = true;
    public int iDwgOneLineBranch = -3; //typically negative. Default = 0 in DM
    public int ixDwgOneLineBranch = 1; //int ref to tblDwgOneLineBranch. Block rep for equipment on SL.
    public int iDwgOneLineWireDisconnect = -2; //typically negative. Default = 0 in DM
    public int ixDwgOneLineWireDisconnect = 2; //int ref to tblDwgOneLineWire. Type of disc on SL
    public int iDwgOneLineWireBreaker = -2; //typically negative. Default = 0 in DM
    public int ixDwgOneLineWireBreaker = 6;  //int ref to tblDwgOneLineWire. Block rep for OCP on SL
    //public int iDwgOneLine = 0; //--THIS IS NOT A PARAMETER IN THE DB--
    public string V_P_W; //TODO this eval'd to Null on a test read
    public string voltage_Parsed; //NON-DM variable. custom field. Not in DM. Truncate the "3P 4W", Leave just "208Y/120V"
    public string LOAD_DES; //this is what gets reported in pnl schedule
    public int GND = 1;
    public int ISO_GND = 0;
    public string LT_DESC_1 = "Motor"; //TODO read this instead
    public double LT_CON_1; //KVA
    public string LT_HP_1; //motor size in HP. Chg'd to string to handle "F".
    public double LT_CAL_1; //NEC connected KVA
    public double LT_FAC_1 = 1; //Connected load multiplier (IE: 1.25 for motor)
    public string LT_DESC_2 = "Motor";
    public double LT_CON_2 = 0;
    public double LT_CAL_2 = 0;
    public int LT_FAC_2 = 1;
    public string LT_DESC_3 = "Motor";
    public double LT_CON_3 = 0;
    public double LT_CAL_3 = 0;
    public int LT_FAC_3 = 1;
    public string LT_DESC_4 = "Motor";
    public double LT_CON_4 = 0;
    public double LT_CAL_4 = 0;
    public int LT_FAC_4 = 1;
    public int Dx = 0;
    public int Dy = 0;
    public int Dz = 0;
    public int dRotation = 0;
    public int d3DAngle = 0;
    public int d3DDistance = 0;
    public int d3DAngleDisconnect = 0;
    public int d3DDistanceDisconnect = 0;
    public int dDiscZ = 0;
    public int iDiscZ_custom = 0;
    public double? dMCA; //is null if not overriden
    public double? dMOCP; //is null if not overriden
    public int FAULT_PN = 0;
    public int dFaultTotalMotor = 0;
    public string D_NOTE; //"Drawing Note 1" - will populate with ID = Primary Key for tracking
    public string R_NOTE = "NO DESCRIPTION"; //"Drawing Note 2" - will populate with load description for tracking
    public string AIC = "Verify w/ Single Line";
}
c# .net ado
1个回答
0
投票

在 OleDb 参数化查询中,最重要的是按照参数在查询文本中出现的顺序添加参数。 OleDb 不使用名称来解析参数。它使用参数集合中的参数位置。您的 ID 参数不在 WHERE 语句中使用的正确位置

因此,要解决您的问题,只需将参数@ID移到两个新参数之后即可

....
cmd.Parameters.AddWithValue("@MCA", motor.dMCA.HasValue ? motor.dMCA.Value : DBNull.Value); //add the safe parameter
cmd.Parameters.AddWithValue("@MOCP", motor.dMOCP.HasValue ? motor.dMOCP.Value : DBNull.Value); //add the safe parameter
cmd.Parameters.AddWithValue("@ID", motor.ixEquL); 
© www.soinside.com 2019 - 2024. All rights reserved.