2010-06-21 2 views
48

Sto cercando di rendere i miei test di integrazione più identi- cienti. Un'idea era quella di eseguire il rollback dopo ogni test, l'altra idea era quella di analizzare in modo analitico il testo, in modo simile alla casella di controllo verde in Query Analyzer o SSMS.Come posso controllare a livello di codice (analizzare) la validità di un'istruzione TSQL?

Come si ottiene SQL Server per analizzare il mio comando senza eseguirlo tramite ADO.NET?

UPDATE: Questo è quello che alla fine ha funzionato, se lo desideri:

using (DbCommand executeOnly = Factory.DbCommand()) 
{ 
    executeOnly.Connection = command.Connection; 
    executeOnly.CommandType = CommandType.Text; 
    executeOnly.CommandText = "SET NOEXEC ON;" + sqlCommand; 
    executeOnly.Connection.Open(); 
    executeOnly.ExecuteNonQuery(); 
} 
//set more properties of command. 
command.Execute(); 

Per motivi inspiegabili, "SET PARSEONLY ON" ha lavorato solo in Query Analyzer. Non ho potuto impostare questo su una connessione ADO.NET. Lo è anche perché PARSEONLY sembra catturare solo gli errori di sintassi, che non è un errore comune. SET NOEXEC ON individuerà una varietà più ampia di errori, ad esempio una vista che fa riferimento a una tabella o colonna mancante oa un parametro mancante in una stored procedure.

+1

Domanda interessante anzi –

+1

sto supponendo che sia 'executeOnly.CommandText = "SET NOEXEC ON; "+ sqlCommand;': 3 – Liz

risposta

36

Penso che il comando che stai cercando sia SET NOEXEC ON. Se si imposta questo per la connessione, le query verranno analizzate ma non verranno eseguite. Un'altra opzione sarebbe SET PARSEONLY ON, ma onestamente non sono sicuro di quale sia la differenza tra i due.

+1

+1, [SET NOEXEC (Transact-SQL)] (http://msdn.microsoft.com/en-us/library/ms188394.aspx) –

+4

In seguito ai commenti sotto la mia risposta , Penso che ci possa essere un bug con SET NOEXEC ON in SQL 2K8 - è stato riprodotto anche da altri. Controlla il bug di MS Connect che ho sollevato: https://connect.microsoft.com/SQLServer/feedback/details/ 569263/set-noexec-on-does-not-flag-up-invalid-nome-oggetto-errori – AdaTheDev

6

SET PARSEONLY: Esamina la sintassi di ogni istruzione Transact-SQL e restituisce eventuali messaggi di errore senza compilare o eseguire l'istruzione.

+0

Questo è ciò che SSMS sta facendo quando si preme la casella di controllo verde. Si può facilmente vederlo accadere in SQL Profiler. – deroby

7

utilizzare la seguente query

SET PARSEONLY ON 
--Your query here 
SET PARSEONLY OFF 
21

+1 alla risposta di Eric. Ma ho trovato SET FMTONLY ON anche essere utile come SET NOEXEC ON non sembra gettare tutti gli errori.

ad es.

SELECT * FROM ATableThatDoesNotExist 

esecuzione che con SET NOEXEC ON dice che era successo, nonostante la tabella non esistente nel database. Eseguendolo invece con SET FMTONLY ON, verrà generato l'errore "Nome oggetto non valido".

SET FMTONLY ON restituisce anche i metadati relativi al gruppo di risultati che sarebbe tornato, che può venire molto utile

+0

I ottenere un errore quando si utilizza 'SET NOEXEC ON' e' SELECT * FROM ATableThatDoesNotExist' –

+0

@KM Non viene visualizzato alcun errore in SQL2005 o SQL2008 –

+0

@KM - Come Martin, non viene visualizzato alcun errore:/ – AdaTheDev

6

Davvero Dipende lo scopo dei test.

Il modo più affidabile sarebbe quello di utilizzare il rollback dopo ogni test se le vostre affermazioni si prestano a quello (non sono troppo pesanti per renderlo praticabile).

Ho fatto questo in passato e sono stato contento di essere informato dei problemi di runtime che non avrei catturato in nessun altro modo.

+0

+1 - Sono d'accordo. Realmente eseguire la dichiarazione e fare un rollback dopo sarà il modo più affidabile per testare. –

+0

+1: 'SET NOEXEC ON 'sta solo verificando che la query sia valida. Una query può essere valida, ma non restituire risultati corretti. –

8

SQL Server 2012 possibile analizzare la sintassi, le procedure e le tabelle con le seguenti procedure e funzioni di sistema:

They are supposedly replacing "SET FMTONLY".

li ho testati e funzionano molto meglio di "SET NOEXEC ON" e "SET PARSEONLY ON"

Esempi:

non viene generato un errore :

Invia correttamente un errore ("SET NOEXEC" e "SET PARSEONLY" non genera un errore in questo caso):

sp_describe_undeclared_parameters 
    @tsql = N'SELECT object_id, name, type_desc FROM sys.indexes;SELECT object_id, name, type_desc FROM sys.NOTaTABLE;'