2010-11-15 7 views
7

Oggi mi sono imbattuto in un problema interessante. Stavo alterando una procedura memorizzata e ho messo un'istruzione select alla fine. Doveva essere temporaneo e solo per lavorare con i dati. Sono stato sorpreso di scoprire più tardi che la dichiarazione è stata salvata ed era in esecuzione ogni volta che la SP funzionava.Dichiarazioni dopo END in stored procedure

SET ANSI_NULLS ON 
GO 

-- Comments usually go here and are saved as part of the SP 
ALTER PROCEDURE [dbo].[MySP] 
    @param INT 
AS 
BEGIN 
    --Your normal SQL statements here 
END 

--You can also add SQL statements here 
select * from LargeTable 

--You have access to the params 
select @param 

ha senso che tutto viene salvato, non solo ciò che è dentro BEGIN/END, altrimenti i commenti e SET ANSI_NULLS, ecc scomparirebbe. Sono un po 'confuso con ciò che inizia dove, quindi ho un paio di domande:

  1. SET ANSI_NULLS viene salvato come parte del SP. Ho confermato che ogni SP ha il suo valore. In che modo SQL Server sa di salvarlo come parte dell'SP poiché non è stato referenziato prima? Esegue una scansione completa dello stato dell'ambiente corrente, quindi quando viene eseguito lo stato ALTER PROCEDURE salva lo stato (probabilmente solo valori non predefiniti)?
  2. Apparentemente BEGIN/END sono opzionali e non hanno alcun significato intrinseco. Perché sono inclusi anche allora? Danno un falso senso dello scope che non esiste. A me non sembra BEGIN/END e un GO alla fine sarebbe più sensato.
+1

BEGIN/END sono usati per scopo, come contenente istruzioni multiple in un if/while/etc. Francamente, TSQL è atroce da lavorare rispetto a PLSQL, che è molto più strutturato/organizzato nel modo in cui utilizza BEGIN/END e utilizza il punto e virgola per terminare le linee. Come TSQL richiede un punto e virgola prima di un WITH/CTE se si dichiarano variabili prima di esso ...:/Chiunque abbia un'esperienza di linguaggio basata su C può ricevere PLSQL e riuscire a leggerlo. Non posso dirlo per TSQL ... –

+0

@OMG - Quindi quale "scope" dà in questo caso? L'unica cosa che posso immaginare è se dichiari una variabile all'interno di BEGIN/END che non è disponibile all'esterno. Perché dovresti mai mettere le dichiarazioni SQL al di fuori; perché non dovresti mettere tutto fuori e no BEGIN/END? –

+1

L'esempio è valido, non ho detto che era sapiente;) –

risposta

5

ANSI NULLS e QUOTED IDENTIFIERS sono memorizzati come attributi dei metadati del codice di procedura memorizzato. È possibile rivedere le impostazioni tramite

select * from sys.sql_modules 

Quando una procedura viene salvato, questi attributi sono impostati su quello che sono per il collegamento attraverso il quale la procedura è in corso il salvataggio. Questo può portare a irritanti incoerenze, quindi fai attenzione.

Come per BEGIN/END, è esattamente come dice @bobs: indicano i blocchi di codice, non indicano l'inizio e la fine del codice di stored procedure. (Funzioni, sì, procedure, no.) Come dici tu, no BEGIN/END and a GO at the end would make the most sense è il modo in cui lo faccio da anni.

Tecnicamente, SQL tenterà di salvare tutto in un batch come parte della stored procedure, ovvero tutto il testo inviato, suddiviso in istruzioni GO (se presenti). Se hai bloccato un'istruzione RETURN proprio prima delle tue query ad hoc, saranno incluse nel codice ma non verranno mai eseguite.

+0

+1 per 'sys.sql_modules' e tale funzione DO usa' BEGIN/END'. L'unico problema con 'GO' alla fine è che non è generato dall'opzione di modifica, quindi la prossima volta non è lì. Ma almeno il 'BEGIN/END' non c'è neanche. –

5

Il BEGIN...END definisce un blocco di codice. Non definisce l'inizio e la fine di uno script o una procedura. Ma sono d'accordo che può essere fonte di confusione.

Le impostazioni SET QUOTED_IDENTIFIER e SET ANSI_NULLS vengono salvate ma non le altre impostazioni. Scopri l'interoperabilità here per ulteriori informazioni.

+0

Questo risponde alla mia prima domanda, grazie: 'Motore di database salva le impostazioni di SET QUOTED_IDENTIFIER e SET ANSI_NULLS quando una procedura Transact-SQL viene creata o modificata ... Altre opzioni SET, come SET ARITHABORT, SET ANSI_WARNINGS, o SET ANSI_PADDINGS non vengono salvati quando viene creata o modificata una procedura.Se la logica della procedura dipende da una particolare impostazione, includere una istruzione SET all'inizio della procedura per garantire l'impostazione appropriata. –

1

racchiude una serie di Transact-SQL istruzioni in modo che un gruppo di istruzioni SQL può essere eseguito . BEGIN e END sono parole chiave in linguaggio controllo-del-flusso.

Quando SET ANSI_NULLS è ON, una dichiarazione SELECT che utilizza WHERE nome_colonna = NULL restituisce zero righe anche se ci sono valori nulli in column_name. Un'istruzione SELECT che utilizza WHERE nome_colonna <>NULL restituisce zero righe anche se non ci sono valori non nulli in nome_colonna.

Quando SET ANSI_NULLS è OFF, gli operatori di confronto Uguale (=) e Non uguale a (<>) non seguono lo standard ISO. Un'istruzione SELECT che utilizza WHERE column_name = NULL restituisce le righe che hanno valori Null in column_name. Un SELECT dichiarazione che utilizza WHERE nome_colonna <>NULL restituisce le righe che hanno valori non Null nella colonna. Inoltre, un'istruzione SELECT che utilizza WHERE nome_colonna <> XYZ_value restituisce tutte le righe che non sono XYZ_value e che non sono NULL.

Quando SET ANSI_NULLS è ON, tutti i confronti con un valore nullo valutano su UNKNOWN. Quando SET ANSI_NULLS è OFF, il confronto di tutti i dati con un valore Null restituiscono TRUE se il valore dei dati è NULL. Se non è specificato SET ANSI_NULLS, si applica l'impostazione dell'opzione ANSI_NULLS del database corrente. Per ulteriori informazioni sull'opzione del database ANSI_NULLS, vedere ALTER DATABASE (Transact-SQL) e Impostazione delle opzioni del database.

SET ANSI_NULLS ON influenza un confronto solo se uno degli operandi del confronto è una variabile NULL o un valore letterale NULL. Se entrambi i lati del confronto sono colonne o espressioni composte, l'impostazione non influisce sul confronto.

Per uno script a funzionare come previsto, indipendentemente dall'opzione ANSI_NULLS database o l'impostazione di SET ANSI_NULLS, l'utilizzo è NULL e IS NOT NULL a confronti che potrebbero contenere valori nulli.

SET ANSI_NULLS deve essere impostata su ON per l'esecuzione di query distribuite. ANSI_NULLS

SET deve essere attivo anche durante la creazione o la modifica di indici su colonne calcolate o viste indicizzate. Se SET ANSI_NULLS è OFF, tutte le istruzioni CREATE, UPDATE, INSERT e DELETE su tabelle con indici su colonne calcolate o viste indicizzate avranno esito negativo. SQL Server restituirà un errore che elenca tutte le opzioni SET che violano i valori richiesti. Inoltre, quando si esegue un'istruzione SELECT, se SET ANSI_NULLS è OFF, SQL Server ignorerà i valori dell'indice su colonne o viste calcolate e risolverà l'operazione di selezione come se non esistessero tali indici nelle tabelle o nelle viste.

+0

Buone informazioni su ANSI_NULLS, ma non direttamente rilevanti per la domanda. Non conoscevo le regole nell'ultimo paragrafo ed è sempre bene imparare di più. –

Problemi correlati