2010-04-09 68 views
2

我在基於c#的asp.net頁面上有一個SqlCommand對象。 SQL和傳遞的參數大部分時間都在運行。我遇到了一種不能正常工作的情況,我收到以下錯誤:從SqlCommand對象發送什麼SQL

字符串或二進制數據將被截斷。該語句已終止。

我知道錯誤,但數據庫中的所有列應該足夠長,以容納所有發送的內容。

我的問題,

有沒有辦法看到實際的SQL發送到數據庫中的哪些是SqlCommand對象?我希望能夠在出現錯誤時通過電子郵件發送SQL。

感謝, 賈斯汀

回答

7

您需要使用SQL Server Profiler來觀看從應用程序會發生什麼。我相信它可以顯示你需要看到的SQL和參數。

+3

這個工具應該是你最好的朋友。 – Bryan 2010-04-10 02:36:44

+0

這是最好的,Microsoft使用一些傻瓜存儲過程而不是生成實際的SQL語句。這讓開發者(我)感到瘋狂。爲什麼他們必須這麼做倒退! – Justin808 2010-05-05 02:58:41

+0

你指的是哪個存儲過程? – 2010-05-05 04:50:23

8

雖然你不能堵塞是成類似企業管理器來運行它適用於記錄。

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(); 
} 
+0

你救了我的一天! 不允許使用探查器,這是獲取實際SQL的好方法,然後從SSMS或企業管理器運行它。 – 2013-01-16 18:09:05

4

雖然並不完美,這裏的東西我撞倒了東西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); 
+0

注意,這需要 [StringExtensions.cs](http://dotnetx.googlecode.com/svn-history/r11/trunk/DotNetX/ExtensionMehods/StringExtensions.cs) 和 [ObjectExtensions.cs](HTTP:/ /dotnetx.googlecode.com/svn-history/r11/trunk/DotNetX/ExtensionMehods/ObjectExtensions.cs) ,但給SQL更好的傾向於SQL Server。 – 2013-01-17 10:01:03

+1

我沒有發現我在代碼中留下了自己的擴展方法(它們不是你提到的但是做同樣的事情),但希望方法名稱暗示它們的上下文! – Flapper 2013-01-30 13:55:53