我公司使用来自众多客户的数据,并忽略了记录数据库的表格和字段所代表的内容。为了帮助解决这个问题,我编写了一些存储过程,这些过程似乎只适用于它们所使用的数据库。我想在服务器上有一个可以在其所有数据库上使用的存储过程实例,但是无法弄清楚如何实现它。以下是程序:
Create Procedure sp_GetTableDocumentation(@TableName SYSNAME)
AS
SELECT
@TableName AS [Table Name]
,'' AS [Column Name]
,CONVERT(NVARCHAR(MAX), ISNULL(D.value, '')) AS [Description]
FROM sys.Tables AS T
OUTER APPLY (SELECT TOP 1 * FROM ::fn_listextendedproperty('Description', 'SCHEMA', 'dbo', 'TABLE', @TableName, NULL, NULL)) AS D
WHERE T.Name = @TableName
UNION ALL
SELECT
@TableName AS [Table Name]
,C.Name AS [Column Name]
,CONVERT(NVARCHAR(MAX), ISNULL(D.value, '')) AS [Description]
FROM sys.Tables AS T
INNER JOIN sys.Columns AS C ON T.Object_id = C.Object_id
OUTER APPLY (SELECT TOP 1 * FROM ::fn_listextendedproperty('Description', 'SCHEMA', 'dbo', 'TABLE', @TableName, 'COLUMN', C.Name)) AS D
WHERE T.Name = @TableName
GO
Create Procedure sp_SetTableDescription(
@schemaName sysname
, @tableName sysname
, @description sql_variant
)
As
If Exists (
Select 1
From fn_listextendedproperty('Description','SCHEMA',@schemaName,'TABLE',@tableName,NULL,NULL)
)
exec sp_DropExtendedProperty 'Description','SCHEMA',@schemaName,'TABLE',@tableName
If (Not @description Is Null) And (Not @description = '')
exec sp_AddExtendedProperty 'Description', @description,'SCHEMA',@schemaName,'TABLE',@tableName
GO
Create Procedure sp_SetTableDescription(
@schemaName sysname
, @tableName sysname
, @description sql_variant
)
As
If Exists (
Select 1
From fn_listextendedproperty('Description','SCHEMA',@schemaName,'TABLE',@tableName,NULL,NULL)
)
exec sp_DropExtendedProperty 'Description','SCHEMA',@schemaName,'TABLE',@tableName
If (Not @description Is Null) And (Not @description = '')
exec sp_AddExtendedProperty 'Description', @description,'SCHEMA',@schemaName,'TABLE',@tableName
GO
CREATE PROCEDURE sp_SetColumnDescription (
@schemaName SYSNAME
,@tableName SYSNAME
,@columnName SYSNAME
,@description SQL_VARIANT
)
AS
IF EXISTS (
SELECT 1
FROM fn_listextendedproperty('Description', 'SCHEMA', @schemaName, 'TABLE', @tableName, 'COLUMN', @columnName)
)
EXEC sp_DropExtendedProperty 'Description','SCHEMA',@schemaName,'TABLE',@tableName,'COLUMN',@columnName
IF (NOT @description IS NULL) AND (NOT @description = '')
EXEC sp_AddExtendedProperty 'Description',@description,'SCHEMA',@schemaName,'TABLE',@tableName,'COLUMN',@columnName
GO
由于
答案 0 :(得分:1)
系统存储过程可以做你想做的事。
通常,存储过程针对编译它的数据库执行。(正如您所注意到的那样)。 如果过程名称以“sp_”开头,则在master db中并标记为sys.sp_MS_MarkSystemObject,则可以像这样调用它:
Exec somedb.dbo.sp_GetTableDocumentation
Exec anotherdb.dbo.sp_GetTableDocumentation
请参阅:https://www.mssqltips.com/sqlservertip/1612/creating-your-own-sql-server-system-stored-procedures/
如果您可以接受将存储过程放入主数据库,这一切都很好。
答案 1 :(得分:0)
您可以使用未记录的系统存储过程sp_MSforeachdb
,但要注意它是未记录的,并且可能随时消失(尽管它至少在2005年以及可能更早的时候在SQL Server中)。
以下是使用sp_MSforeachdb
的第一个存储过程的一部分示例:
DECLARE @Tablename VARCHAR(100) = 'tblPolicy'
DECLARE @sql VARCHAR(MAX) =
'USE [?]
SELECT
T.TABLE_NAME AS [Table Name],
'''' AS [Column Name],
CONVERT(NVARCHAR(MAX), ISNULL(D.value, '''')) AS Description
FROM
INFORMATION_SCHEMA.TABLES T
OUTER APPLY (SELECT TOP 1 * FROM ::fn_listextendedproperty(''Description'', ''SCHEMA'', ''dbo'', ''TABLE'', ''' + @TableName + ''', NULL, NULL)) AS D
WHERE
TABLE_NAME = ''' + @Tablename + ''''
EXEC master.sys.sp_MSforeachdb @sql
另外,请注意SQL注入的威胁,具体取决于@Tablename
值的来源。关于为什么这不是一个好主意可能还有一些其他的警告,但我现在会坚持这些。 ;)