从 SqlCommand 对象发送啥 SQL
Posted
技术标签:
【中文标题】从 SqlCommand 对象发送啥 SQL【英文标题】: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。
谢谢, 贾斯汀
【问题讨论】:
【参考方案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.cs 和ObjectExtensions.cs,但让SQL 更适合SQL Server。 我没有发现我在代码中留下了我自己的扩展方法(它们不是你提到的,但做同样的事情)但希望方法名称暗示它们的上下文!跨度> 【参考方案4】:查看这个问题,它应该提供您正在寻找的内容。
Get the generated SQL statement from a SqlCommand object?
【讨论】:
以上是关于从 SqlCommand 对象发送啥 SQL的主要内容,如果未能解决你的问题,请参考以下文章
SqlCommand.ExecuteReader() 啥时候返回 null?
SqlCommand.CommandTimeout 和 SqlConnection.ConnectionTimeout 有啥区别?