Создание расширенных свойств из существующей таблицы - PullRequest
0 голосов
/ 18 октября 2019

Мне нужно документировать метаданные для полей нескольких таблиц. Я намерен сделать это, добавив таблицы с расширенными свойствами. Единственный способ, которым я делал это в прошлом, - это использование встроенной хранимой процедуры, которая выглядит следующим образом:

ALTER procedure [sys].[sp_addextendedproperty]
@name sysname,
@value sql_variant          = NULL,
@level0type varchar(128)    = NULL,
@level0name sysname         = NULL,
@level1type varchar(128)    = NULL,
@level1name sysname         = NULL,
@level2type varchar(128)    = NULL,
@level2name sysname         = NULL
as

declare @ret int

if datalength(@value) > 7500
begin
    raiserror(15097,-1,-1)
    return 1
end

if @name is null
begin
    raiserror(15600,-1,-1,'sp_addextendedproperty')
    return (1)
end

execute @ret = sys.sp_validname @name
if (@ret <> 0)
begin
    raiserror(15600,-1,-1,'sp_addextendedproperty')
    return (1)
end


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)

В прошлом я делал это просто передавая строкипеременные:

EXEC sys.sp_addextendedproperty 
@name=N'desc_en', 
@value=N'Sex. 1 denotes male, 2 denotes female.' , 
@level0type=N'SCHEMA',
@level0name=N'dbo', 
@level1type=N'TABLE',
@level1name=N'MyTable', 
@level2type=N'COLUMN',
@level2name=N'sex'
GO

Но теперь, когда мне нужно сделать это для нескольких таблиц (и в идеале написать некоторую процедуру, которую можно использовать повторно), я пытаюсь написать функцию, которая принимает динамические (т.е. SELECT) аргументы.

Например, возьмите следующие таблицы. В первом есть пара полей, для которых требуются расширенные свойства, тогда как в другой таблице есть два поля, содержащие эту информацию:

dbo.users:
id | name | sex | year 
-------------------------
 1 | 'john' | 1  | 2019 
 2 | 'jane' | 2  | 2019 

dbo.metadata:
id | property_en | desc_en
-------------------------
 1 | sex         | Sex. 1 denotes male, 2 denotes female
 2 | year        | The year of the event record

desired ep:

EXEC sys.sp_addextendedproperty 
@name=N'desc_en', 
@value=N'Sex. 1 denotes male, 2 denotes female' , 
@level0type=N'SCHEMA',
@level0name=N'dbo', 
@level1type=N'TABLE',
@level1name=N'users', 
@level2type=N'COLUMN',
@level2name=N'sex'

Есть предложения по выводу EP непосредственно из таблицы источника и метаданных, такой как итерация? Первый набор аргументов должен исходить из самой исходной таблицы (т. Е. Информации о схеме, имени таблицы и имени столбца), а второй - из самой таблицы метаданных (т. Е. Property_en и desc_en).

По существупервая таблица (t1) содержит: @ level0name @ level1name

И t2: @name @ value

И соединение выполняется на @ level2name, другими словами, где t1.clmns.name =t2.property_en

1 Ответ

1 голос
/ 18 октября 2019

Вот и мы. Динамический SQL, как это немного сложно, если вы не сделали это очень много. По сути, я просто использую системные таблицы для получения необходимой информации на основе данных в вашей таблице метаданных. Затем мы просто создаем большую строку sql с кучей хранимых вызовов proc. Наконец, мы просто запускаем его.

Обратите внимание, что при этом будет найден любой столбец, который соответствует любой таблице на основе имени в метаданных. Если вам нужно уточнить это для чего-то вроде только таблиц с обоими столбцами или чего-то еще, вам нужно будет немного отрегулировать это.

create table metadata
(
    id int
    , property_en sysname 
    , desc_en varchar(500) 
)

insert metadata values
(1, 'sex', 'Sex. 1 denotes male, 2 denotes female')
, (2, 'year', 'The year of the event record')

declare @SQL nvarchar(max) = ''

select @SQL = @SQL + 'EXEC sys.sp_addextendedproperty @name=N''' + d.property_en + ''', @value=N''' + d.desc_en + ''', @level0type=N''SCHEMA'', @level0name=N''' + s.name + ''', @level1type=N''TABLE'', @level1name=N''' + t.name + ''', @level2type=N''COLUMN'', @level2name=N''' + d.property_en + ''';'
from metadata d
join sys.columns c on c.name = d.property_en
join sys.tables t on t.object_id = c.object_id
join sys.schemas s on s.schema_id = t.schema_id

select @SQL
--once you are comfortable that the dynamic sql works uncomment the line below.
--exec sp_executesql @SQL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...