简体   繁体   English

从扩展属性中获取元数据 (SQL Server)

[英]Get metadata from extended properties (SQL Server)

I am building a data dictionary and trying to get some info from the extended properties.我正在构建一个数据字典并尝试从扩展属性中获取一些信息。

I have a script to add extended properties (working as expected).我有一个脚本来添加扩展属性(按预期工作)。

EXEC sys.sp_addextendedproperty 
@name=N'MS_Description', 
@value=N'This column stores the bla bla bla.' ,
@level0type=N'SCHEMA', 
@level0name=N'dbo', --Schema Name
@level1type=N'TABLE', 
@level1name=N'my_super_crazy_table',--Table Name 
@level2type=N'COLUMN', 
@level2name=N'my_super_crazy_column'--Column Name
GO

Now I want to ideally be able to see when these are created/updated (bonus if I can see what user -- suser_sname() )现在我希望能够看到这些是何时创建/更新的(如果我能看到什么用户 - suser_sname()则奖励)


My final query for the data dictionary is below:我对数据字典的最终查询如下:

SELECT tbl.name as [table_name],
       clmns.name as [column_name],
       exprop.value as [column_description]
       -- exprop.*
FROM sys.tables AS tbl
INNER JOIN sys.all_columns AS clmns ON clmns.object_id=tbl.object_id
LEFT OUTER JOIN sys.extended_properties exprop ON exprop.major_id = clmns.object_id AND exprop.minor_id = clmns.column_id
WHERE (tbl.name IN ('my_super_crazy_table') and exprop.class = 1) 

Output: Output:

     table_name     |     column_name     |       column_description
my_super_crazy_table|my_super_crazy_column|This column stores the bla bla bla.

Is there any other sys table that could give me the information I'm looking for?是否有任何其他sys表可以为我提供我正在寻找的信息? Thanks谢谢

SQL Server doesn't currently store any information about when extended properties are added or updated, or by who. SQL 服务器当前不存储有关何时添加或更新扩展属性或由谁更新的任何信息。

There's quite a bit more logic that you'd probably eventually want to implement.您可能最终想要实现更多的逻辑。 Here's my current best script for it.这是我目前最好的脚本。

https://www.csvreader.com/posts/data_dictionary.sql https://www.csvreader.com/posts/data_dictionary.sql

SELECT
    d.[primary key],
    d.[foreign key],
    CASE
        WHEN LEN(d.[column]) = 0 THEN d.[table]
        ELSE ''
    END AS [table],
    d.[column],
    CAST(d.[description] AS VARCHAR(MAX)) AS [description],
    d.[data type],
    d.nullable,
    d.[identity],
    d.[default]
FROM
    (
        SELECT
            '' AS [primary key],
            '' AS [foreign key],
            s.[name] AS [schema],
            CASE
                WHEN s.[name] = 'dbo' THEN t.[name]
                ELSE s.[name] + '.' + t.[name]
            END AS [table],
            '' AS [column],
            ISNULL(RTRIM(CAST(ep.[value] AS NVARCHAR(4000))), '') AS [description],
            '' AS [data type],
            '' AS nullable,
            '' AS [identity],
            '' AS [default],
            NULL AS column_id
        FROM
            sys.tables t

                INNER JOIN sys.schemas s ON
                    s.[schema_id] = t.[schema_id]

                -- get description of table, if available
                LEFT OUTER JOIN sys.extended_properties ep ON
                    ep.major_id = t.[object_id] AND
                    ep.minor_id = 0 AND
                    ep.name = 'MS_Description' AND
                    ep.class = 1
        WHERE
            t.is_ms_shipped = 0 AND
            NOT EXISTS
            (
                SELECT *
                FROM
                    sys.extended_properties ms
                WHERE
                    ms.major_id = t.[object_id] AND
                    ms.minor_id = 0 AND
                    ms.class = 1 AND
                    ms.[name] = 'microsoft_database_tools_support'
            )

        UNION ALL

        SELECT
            CASE
                WHEN pk.column_id IS NOT NULL THEN 'PK'
                ELSE ''
            END AS [primary key],
            CASE
                WHEN fk.primary_table IS NOT NULL
                    THEN fk.primary_table + '.' + fk.primary_column
                ELSE ''
            END AS [foreign key],
            s.[name] AS [schema],
            CASE
                WHEN s.[name] = 'dbo' THEN t.[name]
                ELSE s.[name] + '.' + t.[name]
            END AS [table],
            c.[name] AS [column],
            ISNULL(RTRIM(CAST(ep.[value] AS NVARCHAR(4000))), '') AS [description],
            CASE
                WHEN uty.[name] IS NOT NULL THEN uty.[name]
                ELSE ''
            END +
                CASE
                    WHEN uty.[name] IS NOT NULL AND sty.[name] IS NOT NULL THEN '('
                    ELSE ''
                END +
                CASE
                    WHEN sty.[name] IS NOT NULL THEN sty.[name]
                    ELSE ''
                END +
                CASE
                    WHEN sty.[name] IN ('char', 'nchar', 'varchar', 'nvarchar', 'binary', 'varbinary')
                        THEN '(' + 
                            CASE
                                WHEN c.max_length = -1 THEN 'max'
                                ELSE 
                                    CASE
                                        WHEN sty.[name] IN ('nchar', 'nvarchar')
                                            THEN CAST(c.max_length / 2 AS VARCHAR(MAX))
                                        ELSE
                                            CAST(c.max_length AS VARCHAR(MAX))
                                    END
                            END
                             + ')'
                    WHEN sty.[name] IN ('numeric', 'decimal')
                        THEN '(' + 
                            CAST(c.precision AS VARCHAR(MAX)) + ', ' + CAST(c.scale AS VARCHAR(MAX))
                             + ')'
                    ELSE
                        ''
                END +
                CASE
                    WHEN uty.[name] IS NOT NULL AND sty.[name] IS NOT NULL THEN ')'
                    ELSE ''
                END AS [data type],
            CASE
                WHEN c.is_nullable = 1 THEN 'Y'
                ELSE ''
            END AS nullable,
            CASE
                WHEN c.is_identity = 1 THEN 'Y'
                ELSE ''
            END AS [identity],
            ISNULL(dc.[definition], '') AS [default],
            c.column_id
        FROM
            sys.columns c
                INNER JOIN sys.tables t ON
                    t.[object_id] = c.[object_id]

                INNER JOIN sys.schemas s ON
                    s.[schema_id] = t.[schema_id]

                -- get name of user data type
                LEFT OUTER JOIN sys.types uty ON
                    uty.system_type_id = c.system_type_id AND
                    uty.user_type_id = c.user_type_id AND
                    c.user_type_id <> c.system_type_id

                -- get name of system data type
                LEFT OUTER JOIN sys.types sty ON
                    sty.system_type_id = c.system_type_id AND
                    sty.user_type_id = c.system_type_id

                -- get description of column, if available
                LEFT OUTER JOIN sys.extended_properties ep ON
                    ep.major_id = t.[object_id] AND
                    ep.minor_id = c.column_id AND
                    ep.[name] = 'MS_Description' AND
                    ep.[class] = 1

                -- get default's code text
                LEFT OUTER JOIN sys.default_constraints dc ON
                    dc.parent_object_id = t.[object_id] AND
                    dc.parent_column_id = c.column_id

                -- check for inclusion in primary key
                LEFT OUTER JOIN
                (
                    SELECT
                        ic.column_id,
                        i.[object_id]
                    FROM
                        sys.indexes i
                            INNER JOIN sys.index_columns ic ON
                                ic.index_id = i.index_id AND
                                ic.[object_id] = i.[object_id]
                    WHERE
                        i.is_primary_key = 1
                ) pk ON
                    pk.column_id = c.column_id AND
                    pk.[object_id] = t.[object_id]

                -- check for inclusion in foreign key
                LEFT OUTER JOIN
                (
                    SELECT
                        CASE
                            WHEN s.[name] = 'dbo' THEN pk.[name]
                            ELSE s.[name] + '.' + pk.[name]
                        END AS primary_table,
                        pkc.[name] as primary_column,
                        fkc.parent_object_id,
                        fkc.parent_column_id
                    FROM
                        sys.foreign_keys fk
                            INNER JOIN sys.tables pk ON
                                fk.referenced_object_id = pk.[object_id]
                            INNER JOIN sys.schemas s ON
                                s.[schema_id] = pk.[schema_id]
                            INNER JOIN sys.foreign_key_columns fkc ON
                                fkc.constraint_object_id = fk.[object_id] AND
                                fkc.referenced_object_id = pk.[object_id]
                            INNER JOIN sys.columns pkc ON
                                pkc.[object_id] = pk.[object_id] AND
                                pkc.column_id = fkc.referenced_column_id
                ) fk ON
                    fk.parent_object_id = t.[object_id] AND
                    fk.parent_column_id = c.column_id
        WHERE
            t.is_ms_shipped = 0 AND
            NOT EXISTS
            (
                SELECT *
                FROM
                    sys.extended_properties ms
                WHERE
                    ms.major_id = t.[object_id] AND
                    ms.minor_id = 0 AND
                    ms.class = 1 AND
                    ms.[name] = 'microsoft_database_tools_support'
            )
    ) d
ORDER BY
    d.[schema],
    d.[table],
    d.column_id;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM