sql >> Base de Datos >  >> RDS >> Sqlserver

Desde .NET, ¿puedo obtener la cadena SQL completa generada por un objeto SqlCommand (con parámetros SQL)?

Un bucle simple que reemplace todos los nombres de los parámetros con sus valores le proporcionará algo similar al resultado final, pero hay varios problemas.

  1. Dado que el SQL nunca se reconstruye usando los valores de los parámetros, no es necesario considerar cosas como líneas nuevas y comillas
  2. Los nombres de los parámetros en los comentarios nunca se procesan realmente por su valor, sino que se dejan tal cual

Con esos en su lugar, y teniendo en cuenta los nombres de parámetros que comienzan con los mismos caracteres, como @NAME y @NAME_FULL , podemos reemplazar todos los nombres de los parámetros con el valor que estaría en el lugar de ese parámetro:

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

Sin embargo, queda un problema con esto, y es que si un parámetro es una cadena, entonces el SQL que inicialmente se ve así:

SELECT * FROM yourtable WHERE table_code = @CODE

se verá así:

SELECT * FROM yourtable WHERE table_code = SOME CODE WITH SPACES

Claramente, esto no es SQL legal, por lo que también debemos tener en cuenta algunos tipos de parámetros:

DbType[] quotedParameterTypes = new DbType[] {
    DbType.AnsiString, DbType.Date,
    DbType.DateTime, DbType.Guid, DbType.String,
    DbType.AnsiStringFixedLength, DbType.StringFixedLength
};
string query = cmd.CommandText;

var arrParams = new SqlParameter[cmd.Parameters.Count];
cmd.Parameters.CopyTo(arrParams, 0);

foreach (SqlParameter p in arrParams.OrderByDescending(p => p.ParameterName.Length))
{
    string value = p.Value.ToString();
    if (quotedParameterTypes.Contains(p.DbType))
        value = "'" + value + "'";
    query = query.Replace(p.ParameterName, value);
}