我有以下代码:
Using cmd As SqlCommand = Connection.CreateCommand
cmd.CommandText = "UPDATE someTable SET Value = @Value"
cmd.CommandText &= " WHERE Id = @Id"
cmd.Parameters.AddWithValue("@Id", 1234)
cmd.Parameters.AddWithValue("@Value", "myValue")
cmd.ExecuteNonQuery
End Using
我想知道是否有任何方法来获得最终的SQL语句作为字符串,它应该看起来像这样:
UPDATE someTable SET Value = "myValue" WHERE Id = 1234
如果有人想知道我为什么要这么做
用于记录(失败的)语句
可以将其复制粘贴到企业管理器中进行测试
从参数命令到非参数命令,可以修改
Using cmd As SqlCommand = Connection.CreateCommand
cmd.CommandText = "UPDATE someTable SET Value = @Value"
cmd.CommandText &= " WHERE Id = @Id"
cmd.Parameters.AddWithValue("@Id", 1234)
cmd.Parameters.AddWithValue("@Value", "myValue")
cmd.ExecuteNonQuery
End Using
To
Private sub Update( byval myID as Int32, byval myVal as String)
Using cmd As SqlCommand = Connection.CreateCommand
cmd.CommandText = "UPDATE someTable SET Value = '" & myVaL & "'" & _
" WHERE Id = " & myID
cmd.ExecuteNonQuery
End Using
End sub
晚回答,我知道,但我也想这样做,所以我可以记录SQL。以下内容很简短,可以满足我的需要。
下面生成的SQL可以在SSMS中复制/粘贴(它正确地将参数替换为值)。您可以添加更多类型,但这满足我在这种情况下使用的所有类型。
private static void LogSQL(SqlCommand cmd)
{
string query = cmd.CommandText;
foreach (SqlParameter prm in cmd.Parameters)
{
switch (prm.SqlDbType)
{
case SqlDbType.Bit:
int boolToInt = (bool)prm.Value ? 1 : 0;
query = query.Replace(prm.ParameterName, string.Format("{0}", (bool)prm.Value ? 1 : 0));
break;
case SqlDbType.Int:
query = query.Replace(prm.ParameterName, string.Format("{0}", prm.Value));
break;
case SqlDbType.VarChar:
query = query.Replace(prm.ParameterName, string.Format("'{0}'", prm.Value));
break;
default:
query = query.Replace(prm.ParameterName, string.Format("'{0}'", prm.Value));
break;
}
}
// the following is my how I write to my log - your use will vary
logger.Debug("{0}", query);
return;
}
现在我可以在执行之前记录SQL:
LogSQL(queryCmd)
queryCmd.ExecuteNonQuery()
也需要覆盖非存储过程,所以我用以下逻辑扩充了CommandAsSql库(见上面@Flapper的回答下的评论):
private static void CommandAsSql_Text(this SqlCommand command, System.Text.StringBuilder sql)
{
string query = command.CommandText;
foreach (SqlParameter p in command.Parameters)
query = Regex.Replace(query, "\\B" + p.ParameterName + "\\b", p.ParameterValueForSQL()); //the first one is \B, the 2nd one is \b, since ParameterName starts with @ which is a non-word character in RegEx (see https://stackoverflow.com/a/2544661)
sql.AppendLine(query);
}
pull请求在:
https://github.com/jphellemons/CommandAsSql/pull/3/commits/527d696dc6055c5bcf858b9700b83dc863f04896
Regex的想法是基于@stambikk和EvZ上面的评论,以及https://stackoverflow.com/a/2544661/903783的“更新:”部分提到了“消极的事后判断”。在正则表达式的开头使用\B而不是\B来进行单词边界检测是因为p.parameterName总是以“@”开头,而“@”不是单词字符。
注意ParameterValueForSQL()是CommandAsSql库中定义的一个扩展方法,用于处理单引号字符串参数值等问题。