我花了一整天的时间来解决这个问题,但似乎找不到解决方案。我将参数 @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";
}
在 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);