我有以下代码:
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);
为我的解决方案使用了Flapper的部分代码,它返回整个SQL字符串,包括在MS SQL SMS中运行的参数值。
public string ParameterValueForSQL(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:
if (sp.Value == DBNull.Value)
{
retval = "NULL";
}
else
{
retval = "'" + sp.Value.ToString().Replace("'", "''") + "'";
}
break;
case SqlDbType.Bit:
if (sp.Value == DBNull.Value)
{
retval = "NULL";
}
else
{
retval = ((bool)sp.Value == false) ? "0" : "1";
}
break;
default:
if (sp.Value == DBNull.Value)
{
retval = "NULL";
}
else
{
retval = sp.Value.ToString().Replace("'", "''");
}
break;
}
return retval;
}
public string CommandAsSql(SqlCommand sc)
{
string sql = sc.CommandText;
sql = sql.Replace("\r\n", "").Replace("\r", "").Replace("\n", "");
sql = System.Text.RegularExpressions.Regex.Replace(sql, @"\s+", " ");
foreach (SqlParameter sp in sc.Parameters)
{
string spName = sp.ParameterName;
string spValue = ParameterValueForSQL(sp);
sql = sql.Replace(spName, spValue);
}
sql = sql.Replace("= NULL", "IS NULL");
sql = sql.Replace("!= NULL", "IS NOT NULL");
return sql;
}
这个方法现在对我很有效。也许它对某人有用。请原谅所有的冗余。
Public Shared Function SqlString(ByVal cmd As SqlCommand) As String
Dim sbRetVal As New System.Text.StringBuilder()
For Each item As SqlParameter In cmd.Parameters
Select Case item.DbType
Case DbType.String
sbRetVal.AppendFormat("DECLARE {0} AS VARCHAR(255)", item.ParameterName)
sbRetVal.AppendLine()
sbRetVal.AppendFormat("SET {0} = '{1}'", item.ParameterName, item.Value)
sbRetVal.AppendLine()
Case DbType.DateTime
sbRetVal.AppendFormat("DECLARE {0} AS DATETIME", item.ParameterName)
sbRetVal.AppendLine()
sbRetVal.AppendFormat("SET {0} = '{1}'", item.ParameterName, item.Value)
sbRetVal.AppendLine()
Case DbType.Guid
sbRetVal.AppendFormat("DECLARE {0} AS UNIQUEIDENTIFIER", item.ParameterName)
sbRetVal.AppendLine()
sbRetVal.AppendFormat("SET {0} = '{1}'", item.ParameterName, item.Value)
sbRetVal.AppendLine()
Case DbType.Int32
sbRetVal.AppendFormat("DECLARE {0} AS int", item.ParameterName)
sbRetVal.AppendLine()
sbRetVal.AppendFormat("SET {0} = {1}", item.ParameterName, item.Value)
sbRetVal.AppendLine()
Case Else
Stop
End Select
Next
sbRetVal.AppendLine("")
sbRetVal.AppendLine(cmd.CommandText)
Return sbRetVal.ToString()
End Function