Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Da .NET posso ottenere la stringa SQL completa generata da un oggetto SqlCommand (con parametri SQL)?

Un semplice ciclo che sostituisce tutti i nomi dei parametri con i loro valori ti fornirà qualcosa di simile al risultato finale, ma ci sono diversi problemi.

  1. Dato che l'SQL non viene mai effettivamente ricostruito utilizzando i valori dei parametri, non è necessario considerare cose come newline e virgolette
  2. I nomi dei parametri nei commenti non vengono mai effettivamente elaborati per il loro valore, ma lasciati così come sono

Con quelli in atto e tenendo conto dei nomi dei parametri che iniziano con gli stessi caratteri, come @NAME e @NAME_FULL , possiamo sostituire tutti i nomi dei parametri con il valore che sarebbe al posto di quel parametro:

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

c'è un problema rimasto con questo, tuttavia, ed è se un parametro è una stringa, quindi l'SQL che inizialmente assomiglia a questo:

SELECT * FROM yourtable WHERE table_code = @CODE

sarà simile a questo:

SELECT * FROM yourtable WHERE table_code = SOME CODE WITH SPACES

Questo chiaramente non è un SQL legale, quindi dobbiamo tenere conto anche di alcuni tipi di parametri:

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