简体   繁体   English

找出哪个查询导致异常

[英]Find out which query caused an exception

I have an OleDbCommand for my inserts that I have tried to implement to avoid SQL injection. 我有一个用于插入的OleDbCommand,我尝试实现该插入以避免SQL注入。 Before that I used simple strings for my queries and I didn't like that. 在此之前,我使用简单的字符串进行查询,但我不喜欢这样。 Now my piece of code for inserting records looks like this: 现在,我用于插入记录的代码如下所示:

 try
 {
    OleDbConnection rConn = new OleDbConnection(args[3]);
    rConn.Open();
    using (OleDbCommand insert = new OleDbCommand(String.Format(Globals.QUERY_INSERT_CLICK, args[4]), rConn))
    {
        insert.Parameters.Add("id", OleDbType.BigInt, 20);
        insert.Parameters.Add("email", OleDbType.VarChar, 255);
        insert.Parameters.Add("clickTime", OleDbType.Date, 20);
        insert.Parameters.Add("subscriberId", OleDbType.BigInt, 20);
        insert.Parameters.Add("link", OleDbType.VarChar, 255);
        insert.Parameters.Add("sendQueueId", OleDbType.BigInt, 20);
        insert.Parameters.Add("mailingListName", OleDbType.VarChar, 255);
        insert.Parameters.Add("newsletterId", OleDbType.BigInt, 20);
        insert.Parameters.Add("sendDate", OleDbType.Date, 20);

        insert.Parameters[0].Value = clickitem.Id;
        insert.Parameters[1].Value = clickitem.Email;
        insert.Parameters[2].Value = clickitem.ClickTime;
        insert.Parameters[3].Value = clickitem.SubscriberId;
        insert.Parameters[4].Value = clickitem.Link;
        insert.Parameters[5].Value = clickitem.SendQueueId;
        insert.Parameters[6].Value = mailingListName;
        insert.Parameters[7].Value = newsletterID;
        insert.Parameters[8].Value = sendDate;

        insert.Prepare();
        insert.ExecuteNonQuery();
    }
    rConn.Close();
}
catch (OleDbException oldbex)
{
    logger.WriteToLog("GETCLICKS", "OleDbException: " + Globals.ERROR_INSERT_CLICK + oldbex.Message);
}
catch (Exception ex)
{
    logger.WriteToLog("GETCLICKS", Globals.ERROR_INSERT_CLICK + ex.Message);
}

I have thousands of inserts and I see from my log that some of them are not correctly inserted. 我有成千上万个插入,并且从我的日志中看到其中一些未正确插入。 The exception tells me eg cannot convert from bigint to datetime and stuff like that. 异常告诉我,例如不能从bigint转换为datetime之类的东西。 Although most of my records are inserted correctly, I want to know which of these insert queries exactly caused the error. 尽管我的大多数记录都已正确插入,但我想知道这些插入查询中的哪一个完全导致了错误。 How can I figure that out? 我该如何解决?

NB Before using this method I had access to my query string and I found the error instantly. 注意:使用此方法之前,我可以访问查询字符串,并且立即发现错误。 Now I guess my immunity to SQL injection is causing some confusion for myself 现在我想我对SQL注入的免疫力给自己带来了一些困惑

Since you mentioned receiving different / multiple data conversion errors, my suggestion would be to improve your logging when catching the OleDbException. 由于您提到收到不同/多个数据转换错误,因此我的建议是在捕获OleDbException时改进您的日志记录。

You could write each of the parameters values to the log right after the initial 'GETCLICKS' log entry. 您可以在初始“ GETCLICKS”日志条目之后立即将每个参数值写入日志。 This would give you a better idea as to what value coming from the user is in the incorrect format. 这将使您更好地了解来自用户的值格式不正确。

Standard SQL erroring won't show you the column or value that caused the error. 标准SQL错误不会显示导致错误的列或值。

Simplest way is to add the SQL statement and parameter values to your logging call. 最简单的方法是将SQL语句和参数值添加到您的日志记录调用中。

string params = string.Join(Environment.NewLine,
                            insert.Parameters
                                  .Select(p => string.Format("{0} : {1}",
                                                             p.Name, 
                                                             p.Value))
                                  .ToArray()
                            );

string message = string.Format("{0}: {1}{2}\n{3}\n{4}",
                               "OleDbException: " ,
                               Globals.ERROR_INSERT_CLICK,
                               oldbex.Message,
                               insert.CommandText,
                               params);

logger.WriteToLog("GETCLICKS", message );

The parameter Value property is of Object generic type. 参数Value属性是Object泛型类型。 So it accepts anything you assign to it. 因此,它接受您分配给它的任何内容。 Of course this is not a good way to handle your data. 当然,这不是处理数据的好方法。 I will try to convert the value to the appropriate datatype for the parameter and avoid to send bogus values to the database. 我将尝试将值转换为参数的适当数据类型,并避免将虚假值发送到数据库。 In this way you will catch the error immediately at the parameter assignement instead of when executing the insert 这样,您将立即在参数分配中捕获错误,而不是执行插入时

For example: 例如:

insert.Parameters[2].Value = Convert.ToDateTime(clickitem.ClickTime);

if this is not a valid datetime it will fail at the Convert.ToDateTime and you will notice that in your log 如果这不是一个有效的日期时间,它将在Convert.ToDateTime处失败,并且您会在日志中注意到这一点

difficult way , but good design . 困难的方法,但是好的设计。 I would recommend that you create your own custom exception class by inheriting the Base Exception class. 我建议您通过继承基础异常类来创建自己的自定义异常类。

Create a constructor which takes oledbcomndand as input parameter and there you can try to log the OldedbComamnd.CommandText by looping over the parameter collection. 创建一个使用oledbcomndand作为输入参数的构造函数,然后您可以尝试通过遍历参数集合来记录OldedbComamnd.CommandText。 as shown in sample below for SQLcommand ( which is more or less same as OLedbCommand) 如下面的SQLcommand示例所示(与OLedbCommand大致相同)

or Easy Way - when exception is thrown , write the OLDEBCommand.ComamndText in log. 还是Easy Way-引发异常时,在日志中写入OLDEBCommand.ComamndText。

Below is a sample i created for StoredProcExecutionException for SQL command. 以下是我为StoredProcExecutionException for SQL命令创建的示例。 you can exactly replicate this for OleDbCommand. 您可以为OleDbCommand完全复制此代码。 hope this helps 希望这可以帮助

 public StoredProcExecutionException(string message, Exception innerException ,SqlCommand sqlCommand)
            : base(Convert.ToString(sqlCommand.CommandType ,CultureInfo.InvariantCulture)+" : "
                + Convert.ToString(sqlCommand.CommandText, CultureInfo.InvariantCulture)
                + "Failed. " + Convert.ToString(message, CultureInfo.InvariantCulture), innerException)
        {
            StringBuilder sb = new StringBuilder();

            foreach (SqlParameter param in sqlCommand.Parameters)
            {
                if (sb.Length > 0) sb.Append(",");
                sb.AppendFormat("{0}='{1}'", param.ParameterName, Convert.ToString(param.Value, CultureInfo.InvariantCulture));               
            }

            StringBuilder sbHeader = new StringBuilder();
            sbHeader.AppendLine(String.Format(CultureInfo.InvariantCulture,"{0} :{1} Failed. {2}", sqlCommand.CommandType, sqlCommand.CommandText, message));
            sbHeader.AppendFormat("Exec {0} ", sqlCommand.CommandText);

            sbHeader.Append(sb.ToString());

        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何找出导致SocketException的端点,UdpClient - How to find out which endpoint caused the SocketException, UdpClient 有没有办法找出导致 NullReferenceException 的对象? - Is there any way to find out which object caused the NullReferenceException? 如果从Microsoft的代码中抛出异常,我如何找出最初导致异常的内容? - How do I find out what originally caused an exception, if it gets thrown from Microsoft's code? 堆栈跟踪如何找出导致异常的方法 - Stack trace how to find out which method is causing an exception 如何找出哪个 nuget package 导致异常? - How to find out which nuget package causes exception? Azure CloudTable.ExecuteBatch(TableBatchOperation)抛出storageexception。 如何找到导致异常的操作? - Azure CloudTable.ExecuteBatch(TableBatchOperation) throws a storageexception. How can I find which operation(s) caused the exception? 简单更新查询导致 System.ComponentModel.Win32Exception: The wait operation timed out error in C# 和 SQL 服务器 - Simple update query caused System.ComponentModel.Win32Exception: The wait operation timed out error in C# and SQL Server 找出特定的异常 - Find out specific Exception NHibernate DateTime进行查询,字符串格式导致溢出异常 - NHibernate DateTime for query, Overflow exception caused by string format Crashlytics中记录“对象引用未设置为对象的实例”异常时,如何找出哪个对象引用为空? - How to find out which object reference is null, when an “Object reference not set to an instance of an object” exception is recorded in Crashlytics?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM