关于c#:System.ArgumentException值不在预期的范围内,SQL问题

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

下面是Database类的相关方法:

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);