2010-04-09 4 views
2

J'ai un objet SqlCommand sur ma page asp.net basée sur C#. Le SQL et les paramètres passés fonctionnent la plupart du temps. J'ai un cas qui ne fonctionne pas, j'obtiens l'erreur suivante:Ce que SQL est envoyé à partir d'un objet SqlCommand

La chaîne ou les données binaires seraient tronquées. La déclaration a été résiliée.

Je comprends l'erreur et toutes les colonnes de la base de données doivent être assez longues pour contenir tout ce qui est envoyé.

Mes questions,

est-il un moyen de voir ce que le SQL réel envoyé à la base de données est de l'objet SqlCommand? Je voudrais être en mesure d'envoyer un courriel SQL quand une erreur se produit.

Merci, Justin

Répondre

7

Vous devez utiliser le Générateur de profils SQL Server pour voir ce qui vient de l'application. Je crois qu'il peut vous montrer le SQL et les paramètres, que vous aurez besoin de voir.

+3

Cet outil devrait être votre nouveau meilleur ami. – Bryan

+0

c'est le meilleur, Microsoft utilise une procédure stockée de fou plutôt que de générer des instructions SQL réelles. Cela rend les choses folles pour les développeurs (moi). Pourquoi doivent-ils tout faire si en arrière! – Justin808

+0

De quelle procédure stockée parlez-vous? –

8

Alors que vous ne serez pas en mesure de brancher est en quelque chose comme Enterprise Manager pour exécuter cela fonctionne pour l'exploitation forestière.

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

Vous avez sauvé ma journée! N'étant pas autorisé à utiliser le profileur, il s'agit d'un excellent moyen d'obtenir le SQL réel, puis de l'exécuter à partir de SSMS ou d'Enterprise Manager. –

4

Alors pas parfait, voici quelque chose que je frappais quelque chose pour TSQL - pourrait facilement être peaufiné pour d'autres saveurs ... Si rien d'autre, il vous donnera un point de départ pour vos propres améliorations :)

Cela fait un travail OK sur les types de données et les paramètres de sortie, similaire à l'utilisation de "exécuter une procédure stockée" dans SSMS. Nous avons surtout utilisé SPs de sorte que le « texte » commande ne tient pas compte des paramètres etc

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

cela génère la sortie le long de ces lignes ...

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

Notez que cela nécessite [StringExtensions.cs] (http://dotnetx.googlecode.com/svn-history/r11/trunk/DotNetX/ExtensionMehods/StringExtensions.cs) et [ObjectExtensions.cs] (http://dotnetx.googlecode.com/svn-history/r11/trunk/DotNetX/ExtensionMehods/ObjectExtensions.cs) mais donne un meilleur SQL à taylored vers SQL Server. –

+1

Je n'avais pas repéré que j'avais laissé mes propres méthodes d'extension dans le code (ce n'est pas celles que vous avez mentionnées mais faites la même chose) mais j'espère que les noms des méthodes impliquent leur contexte! – Flapper