2009-08-10 9 views

risposta

4

No, perché nessuna sostituzione che effettivamente accade. La query viene passata al server così com'è e i parametri vengono passati separatamente.

Tuttavia, è possibile scrivere un metodo per sostituire i segnaposto dei parametri con i valori dei parametri effettivi ... è quello che ho fatto in una delle mie applicazioni, posterò il codice non appena possibile.


Ecco il codice che uso, ma è per un database Oracle Lite, quindi richiederà alcuni adattamenti di usarlo con un altro RDBMS.

public void Log(IDbCommand cmd) 
    { 
     StringBuilder sb = new StringBuilder(cmd.CommandText); 
     for (int i = 0; i < cmd.Parameters.Count; i++) 
     { 
      int pos = sb.ToString().IndexOf("?"); 
      if (pos > 0) 
       sb.Replace("?", FormatParameter(cmd.Parameters[i]), pos, 1); 
     } 
     Log(sb.ToString()); 
    } 

    private string FormatParameter(object prm) 
    { 
     IDbDataParameter p = prm as IDbDataParameter; 
     if (p.Value == null || p.Value == DBNull.Value) 
      return "NULL"; 
     switch (p.DbType) 
     { 
      case DbType.AnsiString: 
      case DbType.AnsiStringFixedLength: 
      case DbType.String: 
      case DbType.StringFixedLength: 
       string s = p.Value as string; 
       return string.Format("'{0}'", s.Replace("'", "''")); 

      case DbType.Binary: 
       byte[] b = p.Value as byte[]; 
       return HexString(b); 

      case DbType.Date: 
      case DbType.DateTime: 
      case DbType.DateTime2: 
       DateTime d = (DateTime)p.Value; 
       return string.Format("to_date('{0}', 'dd/mm/yyyy hh24:mi')", d.ToString("dd/MM/yyyy HH:mm")); 

      default: 
       return p.Value.ToString(); 
     } 
    } 

    private string HexString(byte[] bytes) 
    { 
     StringBuilder sb = new StringBuilder(); 
     for (int i=0; i < bytes.Length; i++) 
      sb.AppendFormat("{0:X2}", bytes[i]); 
     return sb.ToString(); 
    } 
+0

ottimo ... questo aiuta molto! – Toad

2

Beh, si può vedere l'intera query in SQL Profiler (per ammissione cioè dopo che è stato inviato al database), ma ti dà un modo semplice per copiare-incollare l'istruzione in modo da poter eseguire il debug con quello all'interno di Management Studio.

Basta aggiungere una nuova traccia, eseguire il codice che chiama il database, quindi copiare e incollare il comando dagli eventi di acquisizione risultanti.

+0

SQL Profiler è tuo amico. – pjp

+0

funziona anche quando il mio accesso al db è limitato a una stringa di connessione? O ho bisogno di più accesso per eseguire un profiler che può tracciare? – Toad

+0

Le credenziali che stai utilizzando hanno diritti di sysadmin? Se no, allora potresti essere SOL. Forse allora, il codice di Thomas è la soluzione migliore. – davewasthere

0

Ho appena riletto la tua domanda prima di postarla. Anche se questa tecnica probabilmente non può essere applicata direttamente a .net, potresti essere in grado di elaborare qualcosa di simile. Dunque:

Ho recentemente dovuto fare un sacco di codice dinamico in T-SQL, e ho elaborato la seguente routine. Si supponga che hai un pezzo di codice in questo modo:

DECLARE 
    @Command nvarchar(max) 
,@SearchFor int 

SET @Command = 'SELECT * from MyTable where PrimaryKey = @SearchFor' 
SET @SearchFor = 1 

EXECUTE sp_executesql 
    @Command 
,N'@SearchFor int' 
,@SearchFor 

Questo è ovviamente molto simplisitc - se avete bisogno di fare codice dinamico, si sta andando ad avere per query complesse selvaggiamente complesse, e come si Ho scoperto che questi possono essere molto difficili da eseguire il debug. Ecco come mi piacerebbe riscrivere il codice di cui sopra:

DECLARE 
    @Command nvarchar(max) 
,@SearchFor int 
,@Debug  int 
    -- 0 = Run it 
    -- 1 = Run and display it 
    -- 2 = Display it 

SET @Command = 'SELECT * from MyTable where PrimaryKey = @SearchFor' 
SET @SearchFor = 1 
SET @Debug = 1 

IF @Debug > 0 
    -- Show the command that would be run 
    PRINT replace(@Command, '@SearchFor', cast(@SearchFor as varchar(10))) 

IF @Debug < 2 
    -- Run it 
    EXECUTE sp_executesql 
     @Command 
    ,N'@SearchFor int' 
    ,@SearchFor 

Si tratta di codice aggiuntivo di scrivere ed eseguire il debug, ma una volta che è in atto e di lavoro può essere prezioso in situazioni di debug. Se fa parte di una procedura memorizzata, imposta @Debug un parametro che assume come valore predefinito 0 e assicurati che, se impostato su 2, la procedura in realtà non esegua nulla.

+0

Posso apprezzare che il piccolo sforzo in più, offre chiaramente molti vantaggi nel reparto di debugging. Potrei dover creare qualcosa di simile (se non esiste già nulla come questo). – Toad

Problemi correlati