我有以下代码:
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
如果有人想知道我为什么要这么做
用于记录(失败的)语句
可以将其复制粘贴到企业管理器中进行测试
我也有这个问题,一些参数化查询或sp的会给我一个SqlException(主要是字符串或二进制数据将被截断),并且语句很难调试(据我所知,目前没有SQL分析器支持SQL Azure)
我在这里看到了很多类似的代码。我最终把我的解决方案放在一个Sql-Library项目中,以备将来使用。
生成器可以在这里使用:
https://github.com/jeroenpot/SqlHelper/blob/master/Source/Mirabeau.MsSql.Library/SqlGenerator.cs
它支持两种CommandType。文本和命令类型。StoredProcedure
如果你安装了nuget-package,你可以用下面的语句生成它:
SqlDebugHelper.CreateExecutableSqlStatement(sql, parameters);
如果你要转换命令文本:
Private Function ConvToNonParm(ByRef Cmd As SqlClient.SqlCommand) As String
For myCnt As Int16 = 1 To Cmd.Parameters.Count
Dim myVal As String = Cmd.Parameters(myCnt - 1).Value
Select Case Cmd.Parameters(myCnt - 1).SqlDbType
Case SqlDbType.Char, SqlDbType.NChar, SqlDbType.VarChar, SqlDbType.NChar, SqlDbType.NVarChar 'and so on
myVal = "'" & myVal & "'"
'Case "others...."
Case Else
'please assing
End Select
Cmd.CommandText = Replace(Cmd.CommandText, Cmd.Parameters(myCnt - 1).ToString, myVal)
Next
Cmd.Parameters.Clear()
Return Cmd.CommandText
End Function
现在你可以像下面这样获得非参数commandtext:
myCmd.CommandText = "UPDATE someTable SET Value = @Value"
myCmd.CommandText &= " WHERE Id = @Id"
myCmd.Parameters.AddWithValue("@Id", 1234)
myCmd.Parameters.AddWithValue("@Value", "myValue")
myCmd.CommandText = ConvToNonParm(myCmd)
结果是“更新someTable SET值= 'myValue' WHERE Id = 1234”,不再带参数
也需要覆盖非存储过程,所以我用以下逻辑扩充了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库中定义的一个扩展方法,用于处理单引号字符串参数值等问题。
我也有这个问题,一些参数化查询或sp的会给我一个SqlException(主要是字符串或二进制数据将被截断),并且语句很难调试(据我所知,目前没有SQL分析器支持SQL Azure)
我在这里看到了很多类似的代码。我最终把我的解决方案放在一个Sql-Library项目中,以备将来使用。
生成器可以在这里使用:
https://github.com/jeroenpot/SqlHelper/blob/master/Source/Mirabeau.MsSql.Library/SqlGenerator.cs
它支持两种CommandType。文本和命令类型。StoredProcedure
如果你安装了nuget-package,你可以用下面的语句生成它:
SqlDebugHelper.CreateExecutableSqlStatement(sql, parameters);