2017-02-06 9 views
2

エラーが発生し、発生したコード行でSSMSにメッセージが表示されたら、その行の内容を探したいと思うでしょう。SQL ServerはCREATE/ALTERとEXECを結合します

しかし、私はバグに出くわしました。 SQL Serverで次のコードを実行すると、再帰的な関数呼び出しが行われます。 ALTERはAS BEGIN ... END行の後にあっても、ストアドプロシージャの一部としてEXECを受け付けるように見えます。

ALTER PROCEDURE SP_GetErrorLine(
    @lineNum INT, 
    @spName NVARCHAR(250) 
) AS BEGIN 
    SET NOCOUNT ON 
    CREATE TABLE #spLine (
     line INT NOT NULL IDENTITY(1,1), 
     Bob NVARCHAR(2048) NOT NULL 
    ) 

    INSERT INTO #spLine (Bob) 
     EXEC sp_helptext @spName 

    DECLARE @line NVARCHAR(2048) 

    SELECT @line=Bob FROM #spLine 
     WHERE [email protected] 

    DROP TABLE #spLine; 

    SELECT @lineNum AS [Line No.], LTRIM(RTRIM(@line)) AS [SP Line] 
END 

EXEC SP_GetErrorLine 67, 'SP_AnotherProcedure' 

(あなたがSP_AnotherProcedureでそれを実行する必要がありますあなたが同じDBを持っている任意の他のストアドプロシージャに置き換える。)

は、この予想される動作です、またはそれは、コードを誤って解析していますか?

乾杯

+4

BEGIN/ENDはバッチターミネータではありません。あなたが経験していることは、それがどのように行動すべきかです。複数のスクリプトを作成する場合は、バッチ区切りをバッチ間に配置する必要があります。デフォルトのバッチ区切り記号はGOです。あなたの質問への答えではありませんが、あなたはこの記事を見るかもしれません。 http://sqlperformance.com/2012/10/t-sql-queries/sp_prefix –

+1

Seanの要点をさらに詳しく説明するには、 'BEGIN' /' END'(これらは必要ではありません)を取り出してください。ストアドプロシージャはまだ作成されます。 SQL Serverは 'END'をブロックの終わりとみなし、プロシージャの終わりではないので、それ以降のものもプロシージャの一部になります。 –

+0

ああ、感謝@SeanLange、そのパフォーマンスのおしゃべりを知らなかった。いくつかの名前を変更する時間。 – Phi

答えて

1

は/ ENDは、バッチターミネータではありませんBEGIN。あなたが経験していることは、それがどのように行動すべきかです。複数のスクリプトを作成する場合は、バッチ区切りをバッチ間に配置する必要があります。デフォルトのバッチ区切り記号はGOです。

これは、1つのバッチに任意の数のBEGIN/ENDブロックを持つことができると言われています。本当のトリックはバッチをブロックと混同しているわけではありません。

+0

また、間に文を入れないで 'BEGIN END'を行うことはできません - ENDの近くでは不正な構文と見なされます。なぜなら、' BEGIN/END'が前置された条件なしで使用できるのを理解できなかった理由を説明するかもしれません。 – Phi

関連する問題