Stringhe SQL rispetto a istruzioni SQL condizionali

2

C'è un vantaggio nel frammentare le stringhe sql insieme con le istruzioni sql condizionali nello stesso SQL Server? Ho solo circa 10 mesi di esperienza SQL, quindi potrei parlare per pura ignoranza qui.

Dove lavoro, vedo persone che costruiscono intere query in stringhe e concatenano insieme stringhe a seconda delle condizioni. Ad esempio:

Set @sql = 'Select column1, column2 from Table 1 '

If SomeCondtion
    @sql = @sql + 'where column3 = ' + @param1
else
    @sql = @sql + 'where column4 = ' + @param2

Questo è un esempio molto semplice, ma quello che vedo qui è costituito da più join e da enormi query create da stringhe e quindi eseguite. Alcuni di loro scrivono anche che cosa è fondamentalmente una funzione da eseguire, tra cui dichiarazioni Declare, variabili, ecc. C'è un vantaggio nel farlo in questo modo quando si può fare con le sole condizioni nello stesso sql? Per me, sembra molto più difficile eseguire il debug, modificare e persino scrivere vs aggiungere casi, if-elses o ulteriori parametri in cui ramificare la query.

    
posta Yatrix 31.05.2012 - 17:18
fonte

5 risposte

3

SQL dinamico viene utilizzato in situazioni in cui le condizioni non sono note in anticipo. Un esempio a cui mi sono imbattuto spesso è un modulo di ricerca "avanzato" in cui l'utente può cercare su più campi e può cercare oltre semplici ricerche di sottostringa in cui è possibile specificare un valore di ricerca che deve corrispondere esattamente (OR corrisponde come sottostringa e la distinzione tra maiuscole e minuscole è un'opzione) e per valori numerici / di data è possibile specificare operatori & gt ;, & lt ;, > =, < =. Potrebbe anche accadere che un modulo di ricerca stia effettivamente cercando più tabelle unite. In questo caso, è molto più facile creare una query al volo come una stringa ed eseguirla in quel modo, piuttosto che cercare di immaginare ogni possibile query che l'utente può inviare e fare in modo che i blocchi if-else scelgano una query preesistente.

Sei corretto però. SQL dinamico può essere molto difficile eseguire il debug (durante il debug, aggiungo il codice per stampare la query con e senza i valori di sostituzione prima di eseguirlo) e può anche funzionare più lentamente.

    
risposta data 31.05.2012 - 17:32
fonte
3

In primo luogo, la concatenazione di stringhe è una pratica pericolosa. In teoria, va bene se si concatenano stringhe parametrizzate come:

sql += "where foo = @param";
...
command["@param"] = <some value>;

Altrimenti, è soggetto a attacchi di SQL injection.

Ma più al punto, la risposta è temuta, "dipende". Un'enorme query può essere molto veloce se le tabelle del database sono indicizzate per tali scenari. D'altra parte, spesso il client capisce le condizioni e il sottoinsieme di dati che ha bisogno di meglio del server di database. Nell'esempio che hai fornito, è ragionevole che il client personalizzi la sua clausola WHERE prima di eseguirla.

Avere il client personalizzare la sua query ed estrarre i dati di cui ha bisogno può distribuire il lavoro meglio, ma, ancora una volta, dipende da ciò per cui sono progettate le tabelle. Ad un estremo, alcuni schemi sono progettati per essere alla carta, con prestazioni migliori con molte piccole query ad hoc contro tabelle individuali. Altri schemi sono progettati per esporre solo una serie limitata di proc ottimizzati altamente ottimizzati, da cui non ci si deve allontanare. In quest'ultimo caso, avresti ragione - dovrebbero andare con query più grandi. Nel primo caso, è del tutto ragionevole che il cliente prenda la sua parte del processo decisionale.

    
risposta data 31.05.2012 - 17:41
fonte
3

Sembra che tu stia lavorando con un mucchio di Spaghetti Code. Non c'è motivo per cui la costruzione di stringhe sql non possa essere suddivisa in pezzi strutturati e più gestibili. Probabilmente si tratta di preferire il linguaggio di programmazione o tsql. Personalmente, penso che costruire istruzioni SQL in codice sia sempre un casino. Nel tuo caso, non sembra che usare un ORM sia un'opzione a meno che tu non riesca a convincere il resto della squadra / i responsabili.

Non sono sicuro che un'istruzione SQL pre-scritta e autonoma con tutte le condizioni sia più facile eseguire il debug rispetto a più semplici istruzioni generate da condizioni codificate nella lingua scelta. O si può fare male.

EDIT: stai proponendo qualcosa di simile?

Select column1, column2 from Table 1 
where (SomeCondtion = 0 and column3 = @param1)
 or (SomeCondition = 1 and column4 =  @param2) 
    
risposta data 31.05.2012 - 17:44
fonte
0

Esempio classico di bisogno di un pattern Builder

Prova a creare una query SQL come risultato di un'interfaccia fluente. Hibernate per Java lo fa per la API dei criteri :

List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
    .add( Restrictions.disjunction()
        .add( Restrictions.isNull("age") )
        .add( Restrictions.eq("age", new Integer(0) ) )
        .add( Restrictions.eq("age", new Integer(1) ) )
        .add( Restrictions.eq("age", new Integer(2) ) )
    ) )
    .list();

Naturalmente, il loro approccio è una soluzione SQL generica, il tuo builder potrebbe essere mirato esattamente a un tipo di query che necessitava di una costruzione dinamica in fase di runtime.

    
risposta data 31.05.2012 - 17:52
fonte
0

In realtà ho già creato query simili in passato quando SomeCondition non è qualcosa che il server SQL potrebbe / dovrebbe possibilmente sapere

Ad esempio, se SomeCondition è un controllo per vedere se un CheckBox è selezionato o no, allora non c'è modo in cui il server SQL potrebbe o dovrebbe saperlo

È stato anche perché non ero a mio agio nel creare stored procedure in SQL, tuttavia da allora mi sono reso molto più comodo con SQL Server e ora creerò una procedura memorizzata che accetta un parametro IsChecked . È molto più facile da mantenere e eseguire il debug e i rischi di un attacco di SQL injection sono inferiori.

Ci sono molti sviluppatori che non sono a proprio agio con la creazione di stored procedure in SQL, e con loro, è più veloce / più facile usare il linguaggio di programmazione per costruire nelle loro condizioni invece di costruire una stored procedure in SQL Server.

    
risposta data 31.05.2012 - 18:10
fonte

Leggi altre domande sui tag