web-dev-qa-db-fra.com

Vérifiez si la description de la propriété étendue existe déjà avant d'ajouter

J'ai donc un script qui ajoute des propriétés étendues, certaines décrivant une table, d'autres décrivant une colonne. Comment puis-je vérifier si la propriété étendue existe avant de l'ajouter afin que le script ne génère pas d'erreur?

30
ScubaSteve

Ce premier script vérifie si la propriété étendue décrivant la table existe:

IF NOT EXISTS (SELECT NULL FROM SYS.EXTENDED_PROPERTIES WHERE [major_id] = OBJECT_ID('Table_Name') AND [name] = N'MS_Description' AND [minor_id] = 0)
EXECUTE sp_addextendedproperty @name = N'MS_Description', @value = N'This table is responsible for holding information.', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'Table_Name';

Ce second script vérifie si la propriété étendue décrivant la colonne existe:

IF NOT EXISTS (SELECT NULL FROM SYS.EXTENDED_PROPERTIES WHERE [major_id] = OBJECT_ID('Table_Name') AND [name] = N'MS_Description' AND [minor_id] = (SELECT [column_id] FROM SYS.COLUMNS WHERE [name] = 'Column_Name' AND [object_id] = OBJECT_ID('Table_Name')))
EXECUTE sp_addextendedproperty @name = N'MS_Description', @value = N'This column is responsible for holding information for table Table_Name.', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'Table_Name', @level2type = N'COLUMN', @level2name = N'Column_Name';
52
ScubaSteve

Voici une autre approche de procédure stockée similaire à celle de Ruslan K. 

-- simplify syntax for maintaining data dictionary

IF OBJECT_ID ('dbo.usp_addorupdatedescription', 'P') IS NOT NULL
    DROP PROCEDURE dbo.usp_addorupdatedescription;
GO

CREATE PROCEDURE usp_addorupdatedescription
        @table nvarchar(128),  -- table name
        @column nvarchar(128), -- column name, NULL if description for table
        @descr sql_variant     -- description text
AS
    BEGIN
        SET NOCOUNT ON;

        IF @column IS NOT NULL
            IF NOT EXISTS (SELECT NULL FROM SYS.EXTENDED_PROPERTIES
            WHERE [major_id] = OBJECT_ID(@table) AND [name] = N'MS_Description'
                  AND [minor_id] = (SELECT [column_id]
                                    FROM SYS.COLUMNS WHERE [name] = @column AND [object_id] = OBJECT_ID(@table)))
                EXECUTE sp_addextendedproperty @name = N'MS_Description', @value = @descr,
                                               @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE',
                                               @level1name = @table, @level2type = N'COLUMN', @level2name = @column;
            ELSE
                EXECUTE sp_updateextendedproperty @name = N'MS_Description',
                                                  @value = @descr, @level0type = N'SCHEMA', @level0name = N'dbo',
                                                  @level1type = N'TABLE', @level1name = @table,
                                                  @level2type = N'COLUMN', @level2name = @column;
        ELSE
            IF NOT EXISTS (SELECT NULL FROM SYS.EXTENDED_PROPERTIES
            WHERE [major_id] = OBJECT_ID(@table) AND [name] = N'MS_Description'
                  AND [minor_id] = 0)
                EXECUTE sp_addextendedproperty @name = N'MS_Description', @value = @descr,
                                               @level0type = N'SCHEMA', @level0name = N'dbo',
                                               @level1type = N'TABLE', @level1name = @table;
            ELSE
                EXECUTE sp_updateextendedproperty @name = N'MS_Description', @value = @descr,
                                                  @level0type = N'SCHEMA', @level0name = N'dbo',
                                                  @level1type = N'TABLE', @level1name = @table;
    END
GO
5
Brian Westrich

J'ai écrit une procédure stockée simple pour ajouter ou mettre à jour la propriété étendue 'MS_Description':

IF OBJECT_ID ('dbo.usp_addorupdatedescription', 'P') IS NOT NULL
    DROP PROCEDURE dbo.usp_addorupdatedescription;
GO

CREATE PROCEDURE usp_addorupdatedescription
    @table nvarchar(128),  -- table name
    @column nvarchar(128), -- column name, NULL if description for table
    @descr sql_variant     -- description text
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @c nvarchar(128) = NULL;

    IF @column IS NOT NULL
        SET @c = N'COLUMN';

    BEGIN TRY
        EXECUTE sp_updateextendedproperty  N'MS_Description', @descr, N'SCHEMA', N'dbo', N'TABLE', @table, @c, @column;
    END TRY
    BEGIN CATCH
        EXECUTE sp_addextendedproperty N'MS_Description', @descr, N'SCHEMA', N'dbo', N'TABLE', @table, @c, @column;
    END CATCH;
END
GO
3
Ruslan K.

Peut-être que ma réponse ne correspond pas directement à cette question, mais je voudrais souligner que MS_Description est en fait sensible à la casse, même si nous l'ajoutons avec SQL. Si nous utilisons MS_DESCRIPTION au lieu de MS_Description, il n'apparaîtra pas dans la vue de conception de la table SMSS. 

Dans mon cas, je dois faire quelque chose comme ceci pour supprimer la description existante et en ajouter une correcte.

IF EXISTS (
    SELECT NULL
    FROM SYS.EXTENDED_PROPERTIES
    WHERE [major_id] = OBJECT_ID('TableName')
        AND [name] = N'MS_DESCRIPTION'
        AND [minor_id] = (
            SELECT [column_id]
            FROM SYS.COLUMNS
            WHERE [name] = 'ColumnName'
                AND [object_id] = OBJECT_ID('Tablename')
            )
    )
    EXEC sys.sp_dropextendedproperty @name = N'MS_DESCRIPTION'
        ,@level0type = N'SCHEMA'
        ,@level0name = N'dbo'
        ,@level1type = N'TABLE'
        ,@level1name = N'TableName'
        ,@level2type = N'COLUMN'
        ,@level2name = N'ColumnName'
    GO

EXEC sys.sp_addextendedproperty @name = N'MS_Description'
,@value = N'Description detail'
,@level0type = N'SCHEMA'
,@level0name = N'dbo'
,@level1type = N'TABLE'
,@level1name = N'TableName'
,@level2type = N'COLUMN'
,@level2name = N'ColumnName'

ALLER

1
Jansen

Pour vérifier toute propriété étendue disponible pour la table donnée, utilisez la procédure ci-dessous.

IF EXISTS(SELECT 1 FROM sys.extended_properties WHERE [major_id] = OBJECT_ID('<schema>.<table_name>') AND [name] = N'MS_Description')

Si votre table a plusieurs propriétés étendues, indiquez l'ID de colonne sous la forme minor_id.

IF EXISTS(SELECT 1 FROM sys.extended_properties WHERE [major_id] = OBJECT_ID('<schema>.<table_name>') AND [name] = N'MS_Description' AND minor_id = 3)

Consultez la vue catalogue sys.extended_properties pour obtenir toutes les propriétés étendues de votre base de données.

Pour plus de détails, utilisez http://msdn.Microsoft.com/en-us/library/ms177541(v=sql.110).aspx

1
udayanga

Veuillez trouver mon extension à la réponse de Brian Westrich ci-dessus, mais cette version permet la mise à jour et l'ajout de toute propriété étendue sur une table et une colonne, et pas seulement la description MS_Description. En outre, il vous permet d'utiliser la procédure stockée pour ajouter et mettre à jour des propriétés étendues dans différentes bases de données, de sorte que vous n'avez besoin que d'une copie sur un serveur.

CREATE PROCEDURE dbo.AddOrUpdateExtendedProperty
     @Database      NVARCHAR(128)   -- Database name
    ,@Schema        NVARCHAR(128)   -- Schema name
    ,@Table         NVARCHAR(128)   -- Table name
    ,@Column        NVARCHAR(128)   -- Column name, NULL if description for table
    ,@PropertyName  NVARCHAR(128)   -- Property name
    ,@PropertyValue SQL_VARIANT     -- Property value
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @NSQL NVARCHAR(MAX);

    DECLARE @Level2Type NVARCHAR(128) = NULL;

    DECLARE @Params NVARCHAR(MAX) = N'@Schema NVARCHAR(128), @Table NVARCHAR(128), @Column NVARCHAR(128), @PropertyName NVARCHAR(128), @PropertyValue SQL_VARIANT';

    IF @Column IS NOT NULL
    BEGIN
        SET @NSQL = 'USE ' + @Database + ';

            IF NOT EXISTS
            (
                SELECT NULL FROM sys.extended_properties
                 WHERE     major_id = OBJECT_ID(''' + @Schema + '.' + @Table + ''')
                       AND name = @PropertyName
                      AND minor_id = (SELECT column_id
                                        FROM sys.columns
                                       WHERE     name = @Column
                                             AND object_id = OBJECT_ID(''' + @Schema + '.' + @Table + ''')
                                     )
            )
            BEGIN
                EXECUTE sp_addextendedproperty
                     @name = @PropertyName
                    ,@value = @PropertyValue
                    ,@level0type = N''SCHEMA''
                    ,@level0name = @Schema
                    ,@level1type = N''TABLE''
                    ,@level1name = @Table
                    ,@level2type = N''COLUMN''
                    ,@level2name = @Column;
            END
            ELSE
            BEGIN
                EXECUTE sp_updateextendedproperty
                     @name = @PropertyName
                    ,@value = @PropertyValue
                    ,@level0type = N''SCHEMA''
                    ,@level0name = @Schema
                    ,@level1type = N''TABLE''
                    ,@level1name = @Table
                    ,@level2type = N''COLUMN''
                    ,@level2name = @Column;
            END
        ';

        EXECUTE sp_executesql
             @NSQL
            ,@Params
            ,@Schema
            ,@Table
            ,@Column
            ,@PropertyName
            ,@PropertyValue;
    END
    ELSE
    BEGIN
        SET @NSQL = 'USE ' + @Database + ';

            IF NOT EXISTS
            (
                SELECT NULL
                  FROM sys.extended_properties
                 WHERE     major_id = OBJECT_ID(''' + @Schema + '.' + @Table + ''')
                       AND name = @PropertyName
                       AND minor_id = 0
            )
            BEGIN
                EXECUTE sp_addextendedproperty
                     @name = @PropertyName
                    ,@value = @PropertyValue
                    ,@level0type = N''SCHEMA''
                    ,@level0name = @Schema
                    ,@level1type = N''TABLE''
                    ,@level1name = @Table;
            END
            ELSE
            BEGIN
                EXECUTE sp_updateextendedproperty
                     @name = @PropertyName
                    ,@value = @PropertyValue
                    ,@level0type = N''SCHEMA''
                    ,@level0name = @Schema
                    ,@level1type = N''TABLE''
                    ,@level1name = @Table;
            END
        ';

        EXECUTE sp_executesql
             @NSQL
            ,@Params
            ,@Schema
            ,@Table
            ,@Column
            ,@PropertyName
            ,@PropertyValue;
    END
END
0
corky_bantam