【问题标题】:What SQL is being sent from a SqlCommand object从 SqlCommand 对象发送什么 SQL
【发布时间】:2011-02-06 08:59:42
【问题描述】:

我在基于 c# 的 asp.net 页面上有一个 SqlCommand 对象。 SQL 和传递的参数大部分时间都在工作。我有一个案例不工作,我收到以下错误:

字符串或二进制数据将被截断。声明已终止。

我了解错误,但数据库中的所有列都应该足够长以容纳发送的所有内容。

我的问题,

有没有办法查看从 SqlCommand 对象发送到数据库的实际 SQL 是什么?我希望能够在发生错误时通过电子邮件发送 SQL。

谢谢, 贾斯汀

【问题讨论】:

    标签: c# asp.net sql sqlcommand


    【解决方案1】:

    虽然您无法将其插入企业管理器之类的东西来运行它,但它适用于日志记录。

    public static string ToReadableString(this IDbCommand command)
    {
        StringBuilder builder = new StringBuilder();
        if (command.CommandType == CommandType.StoredProcedure)
            builder.AppendLine("Stored procedure: " + command.CommandText);
        else
            builder.AppendLine("Sql command: " + command.CommandText);
        if (command.Parameters.Count > 0)
            builder.AppendLine("With the following parameters.");
        foreach (IDataParameter param in command.Parameters)
        {
            builder.AppendFormat(
                "     Paramater {0}: {1}",
                param.ParameterName,
                (param.Value == null ? 
                "NULL" : param.Value.ToString())).AppendLine();
        }
        return builder.ToString();
    }
    

    【讨论】:

    • 你拯救了我的一天!不允许使用分析器,这是获取实际 SQL,然后从 SSMS 或企业管理器运行它的好方法。
    【解决方案2】:

    您需要使用 SQL Server Profiler 来观察来自应用程序的内容。我相信它可以向您展示您需要查看的 SQL 和参数。

    【讨论】:

    • 这个工具应该是你最好的朋友。
    • 这是最好的,微软使用一些愚蠢的存储过程而不是生成实际的 SQL 语句。这让开发人员(我)变得疯狂。为什么他们必须如此倒退!
    • 你指的是哪个存储过程?
    【解决方案3】:

    虽然不完美,但这是我为 TSQL 设计的一些东西 - 可以很容易地调整为其他风格......如果没有别的,它会给你一个起点,让你自己改进 :)

    这在数据类型和输出参数等方面做得很好,类似于在 SSMS 中使用“执行存储过程”。我们主要使用 SP,因此“文本”命令不考虑参数等

    public static String ParameterValueForSQL(this SqlParameter sp)
      {
       String retval = "";
    
       switch (sp.SqlDbType)
       {
        case SqlDbType.Char:
        case SqlDbType.NChar:
        case SqlDbType.NText:
        case SqlDbType.NVarChar:
        case SqlDbType.Text:
        case SqlDbType.Time:
        case SqlDbType.VarChar:
        case SqlDbType.Xml:
        case SqlDbType.Date:
        case SqlDbType.DateTime:
        case SqlDbType.DateTime2:
        case SqlDbType.DateTimeOffset:
         retval = "'" + sp.Value.ToString().Replace("'", "''") + "'";
         break;
    
        case SqlDbType.Bit:
         retval = (sp.Value.ToBooleanOrDefault(false)) ? "1" : "0";
         break;
    
        default:
         retval = sp.Value.ToString().Replace("'", "''");
         break;
       }
    
       return retval;
      }
    
      public static String CommandAsSql(this SqlCommand sc)
      {
       StringBuilder sql = new StringBuilder();
       Boolean FirstParam = true;
    
       sql.AppendLine("use " + sc.Connection.Database + ";");
       switch (sc.CommandType)
       {
        case CommandType.StoredProcedure:
         sql.AppendLine("declare @return_value int;");
    
         foreach (SqlParameter sp in sc.Parameters)
         {
          if ((sp.Direction == ParameterDirection.InputOutput) || (sp.Direction == ParameterDirection.Output))
          {
           sql.Append("declare " + sp.ParameterName + "\t" + sp.SqlDbType.ToString() + "\t= ");
    
           sql.AppendLine(((sp.Direction == ParameterDirection.Output) ? "null" : sp.ParameterValueForSQL()) + ";");
    
          }
         }
    
         sql.AppendLine("exec [" + sc.CommandText + "]");
    
         foreach (SqlParameter sp in sc.Parameters)
         {
          if (sp.Direction != ParameterDirection.ReturnValue)
          {
           sql.Append((FirstParam) ? "\t" : "\t, ");
    
           if (FirstParam) FirstParam = false;
    
           if (sp.Direction == ParameterDirection.Input)
            sql.AppendLine(sp.ParameterName + " = " + sp.ParameterValueForSQL());
           else
    
            sql.AppendLine(sp.ParameterName + " = " + sp.ParameterName + " output");
          }
         }
         sql.AppendLine(";");
    
         sql.AppendLine("select 'Return Value' = convert(varchar, @return_value);");
    
         foreach (SqlParameter sp in sc.Parameters)
         {
          if ((sp.Direction == ParameterDirection.InputOutput) || (sp.Direction == ParameterDirection.Output))
          {
           sql.AppendLine("select '" + sp.ParameterName + "' = convert(varchar, " + sp.ParameterName + ");");
          }
         }
         break;
        case CommandType.Text:
         sql.AppendLine(sc.CommandText);
         break;
       }
    
       return sql.ToString();
      }
    

    这会按照这些思路生成输出...

    use dbMyDatabase;
    declare @return_value int;
    declare @OutTotalRows BigInt = null;
    exec [spMyStoredProc]
     @InEmployeeID = 1000686
     , @InPageSize = 20
     , @InPage = 1
     , @OutTotalRows = @OutTotalRows output
    ;
    select 'Return Value' = convert(varchar, @return_value);
    select '@OutTotalRows' = convert(varchar, @OutTotalRows);
    

    【讨论】:

    • 请注意,这需要StringExtensions.csObjectExtensions.cs,但让SQL 更适合SQL Server。
    • 我没有发现我在代码中留下了我自己的扩展方法(它们不是你提到的,但做同样的事情)但希望方法名称暗示它们的上下文!跨度>
    【解决方案4】:

    查看这个问题,它应该提供您正在寻找的内容。

    Get the generated SQL statement from a SqlCommand object?

    【讨论】:

      猜你喜欢
      • 2010-09-20
      • 2017-04-07
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-10
      • 2019-09-11
      • 2012-10-31
      相关资源
      最近更新 更多