我在基于 c# 的 asp.net 页面上有一个 SqlCommand 对象。SQL 和传递的参数大部分时间都在工作。我有一个案例不起作用,我收到以下错误:
字符串或二进制数据将被截断。该语句已终止。
我理解错误,但数据库中的所有列都应该足够长以容纳所有发送的内容。
我的问题,
有没有办法查看从 SqlCommand 对象发送到数据库的实际 SQL 是什么?我希望能够在发生错误时通过电子邮件发送 SQL。
谢谢,贾斯汀
我在基于 c# 的 asp.net 页面上有一个 SqlCommand 对象。SQL 和传递的参数大部分时间都在工作。我有一个案例不起作用,我收到以下错误:
字符串或二进制数据将被截断。该语句已终止。
我理解错误,但数据库中的所有列都应该足够长以容纳所有发送的内容。
我的问题,
有没有办法查看从 SqlCommand 对象发送到数据库的实际 SQL 是什么?我希望能够在发生错误时通过电子邮件发送 SQL。
谢谢,贾斯汀
虽然您将无法插入企业管理器之类的东西来运行它,但它适用于日志记录。
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 Server Profiler 来观察来自应用程序的内容。我相信它可以向您展示您需要查看的 SQL 和参数。
虽然不完美,但这是我为 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);
查看这个问题,它应该提供您正在寻找的内容。