2016-01-20 84 views
2

我的公司使用来自众多客户的数据,并忽略记录我们的数据库表和字段所代表的内容。为了解决这个问题,我编写了一些存储过程,这些存储过程似乎只适用于他们所在的数据库。我想在服务器上有一个存储过程的实例,可以在其所有数据库上使用,但无法弄清楚如何实现这一点。下面是程序:SQL存储过程 - 从多个数据库执行

步骤1 - sp_GetTableDocumentation

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 

步骤2 - sp_SetTableDocumentation

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 

程序3 - sp_SetTableDescription

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 

步骤4 - sp_SetColumnDescription

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

对于用户定义的db对象,'sp_'命名约定是不好的做法 – lad2025

+0

这里是一篇文章,介绍为什么sp_是不好的做法。 http://sqlperformance.com/2012/10/t-sql-queries/sp_prefix –

+0

你将不得不实现动态sql来使其成为一组通用的过程,以便您可以定义它将针对哪个数据库执行。它可以完成,但会是一个相当大的工作,因为除了实际使它与动态SQL功能,它也需要从SQL注入安全。 –

回答

1

系统存储过程可以做你想做的事情。

通常情况下,存储过程是针对它编译的数据库执行的(正如您已经注意到的那样)。 如果过程名称以“sp_”开头,位于主数据库中并且标记有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/

这是如果你能接受把你的存储过程中进入主无一不精。

+0

这对我想要做的事很合适。该文章也非常丰富。谢谢你的帮助! – fireflyfiend

0

您可以使用存储过程sp_MSforeachdb的无证系统,但被警告,这是未记录随时都可能消失(尽管它一直在SQL Server至少自2005年甚至更早)。

这是一个使用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值是从哪里来的威胁。为什么这不是一个好主意,可能还有一些其他的警告,但我现在会坚持这些。 ;)

+0

谢谢你的反馈,汤姆。我最终将我的存储过程标记为系统对象,以促进所需的功能。在做了一些更深入的研究之后,我不认为SQL注入将成为我最终解决方案的重要问题。感谢您的建议和谨慎的话语。 – fireflyfiend