Итак, у меня есть script, который добавляет расширенные свойства, некоторые описывают таблицу, некоторые описывают столбец. Как проверить, существует ли расширенное свойство до его добавления, чтобы script не выдавал ошибку?
Проверьте, существует ли расширенное описание свойства перед добавлением
Ответ 1
Этот первый script проверяет, существует ли расширенное свойство, описывающее таблицу:
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';
Этот второй script проверяет, существует ли расширенное свойство, описывающее столбец:
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';
Ответ 2
Вот еще один метод хранимых процедур, аналогичный Руслан К., но это не связано с попытками/уловками или явными транзакциями:
-- 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
Ответ 3
Я написал простую хранимую процедуру для добавления или обновления расширенного свойства "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
Ответ 4
Чтобы проверить любое расширенное свойство, доступное для данной таблицы, используйте, как показано ниже.
IF EXISTS(SELECT 1 FROM sys.extended_properties WHERE [major_id] = OBJECT_ID('<schema>.<table_name>') AND [name] = N'MS_Description')
Если ваша таблица имеет более одного расширенного свойства, укажите идентификатор столбца как 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)
Запрос sys.extended_properties
каталога, чтобы получить все расширенные свойства в вашей базе данных.
Для более подробной информации используйте http://msdn.microsoft.com/en-us/library/ms177541(v=sql.110).aspx
Ответ 5
Возможно, мой ответ не был напрямую связан с этим вопросом, но я хотел бы отметить, что MS_Description на самом деле чувствительна к регистру, даже если мы добавим его с помощью SQL. Если вместо MS_Description мы будем использовать MS_DESCRIPTION, он не будет отображаться в представлении дизайна таблицы SMSS.
В моем случае я должен сделать что-то подобное, чтобы удалить существующее описание и добавить правильное.
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'
ИДТИ
Ответ 6
Пожалуйста, найдите мое расширение ответа Брайана Вестрича выше, но эта версия позволяет обновлять и добавлять любые расширенные свойства таблицы и столбца, а не только описание MS_Description. Кроме того, он позволяет использовать хранимую процедуру для добавления и обновления расширенных свойств в разных базах данных, поэтому вам нужна только одна копия на сервере.
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
Ответ 7
Основываясь на ответе ScubaSteve, следующие запросы позволят вам проверить свойство MS_Description для столбца или таблицы в указанной схеме по имени. Чтобы проверить таблицу, просто замените предикат c.name = '<column>'
на c.name IS NULL
или d.minor_id = 0
Для перечисления свойств MS_Description по схеме используйте -
SELECT a.name as [schema], b.name as [table], c.name as [column], d.name, d.value
FROM sys.schemas a
JOIN sys.tables b ON a.schema_id = b.schema_id
LEFT JOIN sys.columns c ON b.object_id = c.object_id
JOIN sys.extended_properties d ON d.major_id = b.object_id AND d.minor_id = ISNULL(c.column_id,0)
WHERE a.name = '<schema>' AND b.name = '<table>' AND c.name = '<column>' AND d.name = 'MS_Description'
Чтобы проверить, не существует ли свойство MS_Description перед его добавлением, окружите ваш оператор add с помощью -
IF NOT EXISTS (SELECT 1 FROM sys.schemas a JOIN sys.tables b ON a.schema_id = b.schema_id LEFT JOIN sys.columns c ON b.object_id = c.object_id JOIN sys.extended_properties d ON d.major_id = b.object_id AND d.minor_id = ISNULL(c.column_id,0)
WHERE a.name = '<schema>' AND b.name = '<table>' AND c.name = '<column>' AND d.name = 'MS_Description'
)
BEGIN
--EXEC sp_addextendedproperty statement goes here
END
Объединения в этих запросах, вероятно, можно было бы упорядочить лучше, чтобы исключить функцию ISNULL, но это должно получить то, что вы ищете.