SQL Serverのバージョンについては言及していませんが、スクリプトの唯一の違いはであるため、これはsp_recompile
見栄えのする場所のようです。2008R2では、次のロジックがあります。
BEGIN TRANSACTION
-- CHECK VALIDITY OF OBJECT NAME --
-- (1) Must exist in current database
-- (2) Must be a table or an executable object
select @objid = object_id(@objname, 'local')
if @objid is null OR
(ObjectProperty(@objid, 'IsTable') = 0 AND
ObjectProperty(@objid, 'IsExecuted') = 0)
begin
COMMIT TRANSACTION
raiserror(15165,-1,-1 ,@objname)
return @@error
end
そのため、オブジェクトに直接アクセスしようとする前sp_recompile
に、オブジェクトの存在を確認します。オブジェクトが見つからない場合は、重大度-1のエラーが発生します。のドキュメントには、ゼロ未満の重大度レベルはゼロとして解釈されると記載されており、重大度レベルのドキュメントには、重大度ゼロではシステムエラーが発生しないと記載されています。RAISERROR
実際、RAISERROR
fromsp_recompile
をスクリプトに追加すると、影響がないことがわかります@@TRANCOUNT
。
SET XACT_ABORT ON
GO
BEGIN TRANSACTION
CREATE TABLE dbo._test(ID int IDENTITY(1, 1) NOT NULL)
select @@trancount as 'before raiserror'
raiserror(15165,-1,-1 ,'sp_does_not_exist')
select @@trancount as 'after raiserror'
GO
IF @@TRANCOUNT > 0
COMMIT;
@@TRANCOUNT
エラーが発生する前後では1であるため、ロールバックをトリガーするものはありません。ただし、これを行うとSELECT
、データベースエンジンによって「直接」エラーが発生したため、2番目は実行されません。
SET XACT_ABORT ON
GO
BEGIN TRANSACTION
CREATE TABLE dbo._test(ID int IDENTITY(1, 1) NOT NULL)
select @@trancount as 'before raiserror'
exec sp_does_not_exist
select @@trancount as 'after raiserror'
GO
IF @@TRANCOUNT > 0
COMMIT;