SQL Server多步存储过程

时间:2011-10-25 01:18:39

标签: sql sql-server tsql stored-procedures

我有一个基于多个库的软件套件,其中:

1 library = 1 SQL Database。

不同的用户可以拥有对不同库的不同访问权限。

此外,数据库以特定方式命名,以帮助识别哪些是“我的”,哪些不是。“

我想创建一个存储过程,该过程接受一个名为@UserName的变量,并返回名称以MYDB开头的数据库,其中@UserName位于表中{ {1}}。

我想我会从USERS开始,但我不确定如何继续。

我需要知道的是:

  1. 如何迭代sp_databases的结果,只提取名称与我的模式匹配的数据库?
  2. 如何在#1返回的每个数据库的EXEC sp_databases表的@UserName列中检查[USER NAME]
  3. 我猜它与临时表和游标有关,但我不确定从哪里开始。

    任何帮助?

    谢谢!

2 个答案:

答案 0 :(得分:2)

以下是一些概念代码证明,可以向您展示一种方法。 sys.databases包含一个更易于访问的数据库列表。你几乎不得不在某些时候使用动态sql。

CREATE PROCEDURE MyDBs @userName VARCHAR(255)
AS
BEGIN

DECLARE @max INT
DECLARE @i INT 
DECLARE @sql VARCHAR(500)

CREATE TABLE #SQL
(
    rid int identity primary key clustered,
    query varchar(500)
)

INSERT INTO #SQL(query)
SELECT 'SELECT * FROM ['+ name '+].USERS WHERE username = @UserName'
FROM master.sys.databases
WHERE NAME LIKE '%yourpattern%'

SELECT @max = @@rowcount, @i = 1

WHILE @i <= @max
BEGIN
     SELECT @sql = query FROM #sql WHERE rid = @i
     EXEC @sql
     SET @i = @i + 1
END 

DROP TABLE #SQL

答案 1 :(得分:1)

对于1,只需查看sp_databases代码,复制并根据需要进行修改。例如(参见where子句的最后2个条件。这是sp_databases存储过程的实际代码。您可以在主数据库上查看它):

declare @UserName varchar(50)='someuser'
select
        DATABASE_NAME   = db_name(s_mf.database_id),
        DATABASE_SIZE   = convert(int,
                                    case -- more than 2TB(maxint) worth of pages (by 8K each) can not fit an int...
                                    when convert(bigint, sum(s_mf.size)) >= 268435456
                                    then null
                                    else sum(s_mf.size)*8 -- Convert from 8192 byte pages to Kb
                                    end),
        REMARKS         = convert(varchar(254),null)
    from
        sys.master_files s_mf
    where
        s_mf.state = 0 and -- ONLINE
        has_dbaccess(db_name(s_mf.database_id)) = 1 and
        --db_name(s_mf.database_id) like '%'+@UserName+'%' and exists -- you may or may not want to leave this condition here. You'll figure out what condition to use
        (select 1 from databasename.dbo.Users where [UserName]=@UserName)
    group by s_mf.database_id
     order by 1