簡體   English   中英

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:值不在預期范圍內。
在System.Data.SqlClient.SqlParameterCollection.Validate(Int32索引,SqlParameter值)
在System.Data.SqlClient.SqlParameterCollection.AddWithoutEvents(SqlParameter value)
在System.Data.SqlClient.SqlParameterCollection.Add(SqlParameter值)
在MedWMS.Database.startSqlConnection(字符串查詢,SqlParameter []參數,SqlConnection連接,SqlCommand cmd)
在MedWMS.Database。<> c__DisplayClasse.b__8()
在MedWMS.Database.retry(行動)
在MedWMS.Database.executeNonQuery(String query,SqlParameter []參數,String connectionString)...

導致此問題的SQL查詢並不總是相同。 我在SQL Server Management Studio中收到沒有問題的電子郵件后幾秒鍾運行相同的查詢。

我想知道為什么會發生這種情況。 這是關於SO的第一個問題,如果我做錯了,請告訴我。 我很樂意回答任何問題以提供更多細節。

這是導致此錯誤的代碼示例:

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

這是實際傳遞的查詢:

Select InvTermsOverride from SorMaster where SalesOrder = Convert(int, '000000001138325') and InvTermsOverride = '07' --07 is for COD

以下是Database類中的相關方法:

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() + "\r\n" + query2);
}

我有同樣的問題,因為無法解決“Sqlparameter已被另一個SqlparameterCollection包含”

由於某種原因,SQL CE有不同的錯誤。

由於我的重試方法,我無法重用SqlParameter對象,仍然不確定為什么不允許它

無論如何我改變了

cmd.Parameters.Add(sp);

cmd.Parameters.Add(sp.ParameterName, sp.Value);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM