web-dev-qa-db-fra.com

Pourquoi ce retour est-il nécessaire lors de l'utilisation de sp_addextenseProperty dans une procédure stockée?

Dans Entrez la description du lien ici J'ai montré, comment je documente des bases de données.

Pour insérer les propriétés étendues, j'utilise initialement des séquences de plan d'appels sp_addDextenseProperty.

Mais récemment, je voulais attraper les erreurs sur les objets existants lorsque j'exécute le script sur une version plus ancienne de la base de données.

J'ai trouvé le code de travail suivant par essai et error

begin try 
drop procedure dbo.BK_add_Tableproperty
end try begin catch end catch

go
create procedure dbo.BK_add_Tableproperty (
    @table_name sysname,
    @property_name nvarchar(max),
    @Property_value sysname
)
as  
    declare @error integer;
begin try
    EXEC sys.sp_addextendedproperty @name= @property_name,
    @value = @Property_value, 
    @level0type=N'SCHEMA',
    @level0name=N'dbo', 
    @level1type=N'TABLE',
    @level1name=@table_name
end try begin catch
    SET @error = @@ERROR;
    if @error = 15135
        Print 'Table missing no extended properties added: ' + @table_name
    else if @error = 15233
        Print 'Table has already property: ' + @table_name + ' - ' + @property_name
    else
        Print 'unexpected error ' + str(@error)          
    ROLLBACK;  
end catch

go

Ce que moi confond, c'est le fait que je dois ajouter un retour au chemin de capture. AT MSDN J'ai trouvé aucun indice, que sp_addextensedProperty utilise des transactions. Quelqu'un peut-il expliquer cela?

Réponse à GBN:

Mais retour sort de manière inconditionnelle la procédure. Je ne vois que 1 commettre dans chaque chemin:

BEGIN TRANSACTION

begin
    EXEC %%ExtendedPropertySet().AddValue(Name = @name, Value = @value, Level0type = @level0type, Level0name = @level0name, Level1type = @level1type, Level1name = @level1name, Level2type = @level2type, Level2name = @level2name)
    IF @@error <> 0
    begin
        COMMIT TRANSACTION
        return (1)
    end
end

COMMIT TRANSACTION
return (0)

signalé comme bogue à Microsoft Connect:

https://connect.microsoft.com/sqlserver/feedback/details/658556/sp-addextenseProperty-leseves-on-open-Transaction-Quor-an-Error-Occuré

Version améliorée (meilleure manipulation des erreurs et type de paramètre fixe. (le problème initial n'est pas affecté, mais cela handicape NLS dans des messages erronés)

create procedure dbo.BK_add_Columnproperty (
    @table_name sysname,
    @Column_name sysname,
    @property_name nvarchar(max),
    @Property_value sql_variant
)
as  
begin try
    --SET XACT_ABORT ON
    EXEC sys.sp_addextendedproperty @name= @property_name,
    @value = @Property_value, 
    @level0type=N'SCHEMA',
    @level0name=N'dbo', 
    @level1type=N'TABLE',
    @level1name=@table_name,
    @level2type=N'COLUMN',
    @level2name=@Column_name
end try begin catch
    -- SELECT XACT_STATE()    -- returns 1 or -1 when SET XACT_ABORT ON 
    if ERROR_NUMBER() = 15135 -- object invalid
        print '      ' + str(ERROR_NUMBER()) + ' -- ' + ERROR_MESSAGE() 
    else
        print '##### ' + str(ERROR_NUMBER()) + ' -- ' + ERROR_MESSAGE() 
    ROLLBACK;  
end catch

go
5
bernd_k

Cette ligne..

SELECT OBJECT_DEFINITION(OBJECT_ID('sp_addextendedproperty'))

... montre que sp_addextensedProperty a 2 x commit. Ce ne sera pas un problème si la transaction peut être commise (c'est-à-dire non "Doomed" ) mais laissera une transaction ouverte autrement.

Cela pourrait bien être un bug à rapporter sur MS Connect

Un bloc de capture comme celui-ci montrera si la transaction est condamnée

begin catch

SELECT XACT_STATE() -- -1 = doomed, 0 = none, 1 = commit or rollback

    SET @error = ERROR_NUMBER();

    if @error = 15135
        Print 'Table missing no extended properties added: ' + @table_name;
    else if @error = 15233
        Print 'Table has already property: ' + @table_name + ' - ' + @property_name;
    else
        Print 'unexpected error ' + str(@error); 

end catch

Je n'ai pas vu ceci (un TXN ouvert) au travail (SQL Server 2005 SP3) et a reçu les détails d'un serveur SQL local 2008 sur un VM. Pourrait être la version liée.

Edit: vient de voir la mise à jour q

En utilisant SET XACT_ABORT ON FORCE UN ROLLBACK quand même

3
gbn