System.ArgumentException Value does not fall within the expected range, SQL issue
我正在使用.NET Compact 3.5 Windows 7 CE。
我有一个大约有50个用户的应用程序,我有它的设置,这样每当数据库事务失败时,我都会收到一封电子邮件,包括查询。
每隔一段时间,我都会收到一封电子邮件,其中包含一个像这样开始的堆栈跟踪:
System.ArgumentException: Value does not fall within the expected range.
at System.Data.SqlClient.SqlParameterCollection.Validate(Int32 index, SqlParameter value)
at System.Data.SqlClient.SqlParameterCollection.AddWithoutEvents(SqlParameter value)
at System.Data.SqlClient.SqlParameterCollection.Add(SqlParameter value)
at MedWMS.Database.startSqlConnection(String query, SqlParameter[] parameters, SqlConnection connection, SqlCommand cmd)
at MedWMS.Database.<>c__DisplayClasse.b__8()
at MedWMS.Database.retry(Action action)
at MedWMS.Database.executeNonQuery(String query, SqlParameter[] parameters, String connectionString)...
导致此问题的SQL查询并不总是相同的。我在SQL Server Management Studio中收到电子邮件后几秒钟运行相同的查询,没有出现任何问题。
我想知道为什么会发生这种情况。这是我第一个问题,所以如果我做错了请告诉我。我很乐意回答任何问题以提供更多细节。
这是导致此错误的代码示例:
1 2 3 4 5 6 7 | SqlParameter[] parameters = new SqlParameter[1]; parameters[0] = new SqlParameter("@salesOrder", this.salesOrderNumber); string query = @" Select InvTermsOverride from SorMaster where SalesOrder = Convert(int, @salesOrder) and InvTermsOverride = '07' --07 is for COD"; DataTable dt = Database.executeSelectQuery(query, parameters, Country.getCurrent().getSysproConnectionStrReportServer()); |
这是实际传递的查询:
1 | Select InvTermsOverride from SorMaster where SalesOrder = Convert(int, '000000001138325') and InvTermsOverride = '07' --07 is for COD |
下面是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | public static DataTable executeSelectQuery(String query, SqlParameter[] parameters, string connectionString) { DataTable dt = new DataTable(); using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand cmd = null; try { retry(() => { cmd = startSqlConnection(query, parameters, connection, cmd); using (SqlDataReader reader = cmd.ExecuteReader()) { dt.Load(reader); } }); } catch (Exception ex) { onDbConnectionCatch(cmd, ex); } finally { cmd.Dispose(); connection.Close(); } } return dt; } public static void executeNonQuery(String query, SqlParameter[] parameters, string connectionString) { using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand cmd = null; try { retry(() => { cmd = startSqlConnection(query, parameters, connection, cmd); cmd.ExecuteNonQuery(); }); } catch (Exception ex) { onDbConnectionCatch(cmd, ex); } finally { cmd.Dispose(); connection.Close(); } } } private static void retry(Action action) { int retryCount = 3; int retryInterval = 1000; Exception lastException = null; for (int retry = 0; retry < retryCount; retry++) { try { if (retry > 0) System.Threading.Thread.Sleep(retryInterval); action(); lastException = null; return; } catch (Exception ex) { lastException = ex; } } if (lastException != null) { throw lastException; } } private static SqlCommand startSqlConnection(String query, SqlParameter[] parameters, SqlConnection connection, SqlCommand cmd) { if (connection.State != ConnectionState.Open) { connection.Open(); } cmd = new SqlCommand(query, connection); if (parameters != null) { foreach (SqlParameter sp in parameters) { if (sp != null) { cmd.Parameters.Add(sp); } } } return cmd; } private static void onDbConnectionCatch(SqlCommand cmd, Exception ex) { try { new BigButtonMessageBox("","Unable connect to database").ShowDialog(); sendEmailWithSqlQuery(cmd, ex); } catch { } } private static void sendEmailWithSqlQuery(SqlCommand cmd, Exception ex) { string query2 ="cmd was null"; if (cmd != null) { query2 = cmd.CommandText; foreach (SqlParameter p in cmd.Parameters) { query2 = query2.Replace(p.ParameterName,"'" + p.Value.ToString() +"'"); } } InternetTools.sendEmail("DB ERROR", ex.ToString() +" " + query2); } |
我有一个无法解决的问题:"另一个sqlparametercollection已包含sqlparameter"
出于某种原因,SQL CE有一个不同的错误。
由于我的重试方法,我无法重用sqlparameter对象,仍然不确定为什么不允许使用它。
不管怎样我变了
1 | cmd.Parameters.Add(sp); |
到
1 | cmd.Parameters.Add(sp.ParameterName, sp.Value); |