2009-08-10 8 views

Odpowiedz

4

Nie, ponieważ nie podstawienie rzeczywiście dzieje. Kwerenda jest przekazywana do serwera bez zmian, a parametry są przekazywane osobno.

Można jednak napisać metodę zastępowania symboli zastępczych rzeczywistymi wartościami parametrów ... to właśnie zrobiłem w jednej z moich aplikacji, opublikuję kod tak szybko, jak tylko będę mógł.


Oto kod, który używam, ale to jest dla bazy danych Oracle Lite, więc będzie to wymagało pewnych dostosowań go używać z innymi 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

Świetne ... to bardzo pomaga! – Toad

2

Cóż, można zobaczyć całą zapytanie w SQL Profiler (wprawdzie to po że został wysłany do bazy danych), ale pozwala w łatwy sposób skopiować i wkleić oświadczenie więc można debugować z to wewnątrz Management Studio.

Po prostu dodaj nowy ślad, uruchom kod wywołujący bazę danych, a następnie skopiuj i wklej polecenie z wynikowych zdarzeń przechwytywania.

+0

Profil SQL jest twoim przyjacielem. – pjp

+0

czy to działa, nawet jeśli mój dostęp do bazy danych jest ograniczony tylko do ciągu połączenia? A może potrzebuję więcej dostępu, aby uruchomić profiler, który może śledzić? – Toad

+0

Czy poświadczenia, których używasz, mają uprawnienia sysadmin? Jeśli nie, to możesz być SOL. Możliwe, że Kod Thomasa jest najlepszym wyborem. – davewasthere

0

Po prostu ponownie przeczytałem twoje pytanie przed opublikowaniem tego. Chociaż ta technika prawdopodobnie nie może być bezpośrednio zastosowana do .net, być może uda ci się wypracować coś podobnego. A więc:

Niedawno musiałem wykonać wiele dynamicznego kodowania w T-SQL, a ja wymyśliłem następującą procedurę. Załóżmy, że masz kawałek kodu tak:

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 

Jest to oczywiście bardzo simplisitc - jeśli trzeba zrobić kod dynamiczny, masz zamiar mają złożone do szalenie skomplikowane zapytania, a jak ty "odkryłem, że może to być bardzo trudne do debugowania. Oto jak ja przepisać powyższy kod:

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 

Jest to dodatkowy kod do pisania i debugowania, ale kiedy to w miejscu pracy i mogą być nieocenione w sytuacjach debugowania. Jeśli jest to część procedury składowanej, ustaw parametr @Debug na wartość domyślną 0 i upewnij się, że jeśli ustawiono wartość 2, procedura nic nie robi.

+0

Mogę docenić, że niewielki wysiłek dodatkowy, wyraźnie daje wiele korzyści w dziale debugowania. Być może będę musiał stworzyć coś podobnego (jeśli nic takiego już nie istnieje). – Toad

Powiązane problemy