从SqlCommand对象获取生成的SQL语句?

18 浏览
0 Comments

从SqlCommand对象获取生成的SQL语句?

我有以下的代码:

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

如果有人想知道我为什么要这样做:

  • 用于记录(失败的)语句
  • 为了让我有可能将其复制并粘贴到企业管理器中进行测试
admin 更改状态以发布 2023年5月21日
0
0 Comments

虽然不完美,但这是我为TSQL准备的东西,可以轻松调整到其他语言... 如果没有其他用处,至少它可以给你一个自我改进的起点 🙂

这样可以很好地处理数据类型和输出参数等内容,类似于在SSMS中使用“执行存储过程”。我们大多数时候使用SPs,所以“text”命令不考虑参数等内容。

    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);

0
0 Comments

为了记录日志,我很抱歉没有更好的方法,只能自己构造字符串:

string query = cmd.CommandText;
foreach (SqlParameter p in cmd.Parameters)
{
    query = query.Replace(p.ParameterName, p.Value.ToString());
}

0