与存储过程sp_MSforeachdb类似的存储过程sp_MSforeachdb
2006-10-09 22:15
471 查看
遍历数据库的未公开存储过程sp_MSforeachdb应用之Attach数据库
sp_MSforeachdb是SQL Server2k的Master库的未公开存储过程,其作用是遍历SQL实例下多个数据库,执行相应脚本。
比如想知道各数据库的物理文件存放路径和文件名,可以执行如下语句:
exec sp_msforeachdb "select * from ?.dbo.sysfiles"
?就是该存储过程用来替换的DB名称
对于DBA来说,迁移数据库是很经常的事情,常用的方法是停服务后拷贝mdf和ldf到目标服务器,量少时还可以手工操作,量大了就只能使用脚本,有时候一台服务器上有几十个数据库,这时下面的脚本就有了用武之地。
--首先创建接受db信息的临时表
create table DBFileInfo
( dbName varchar(100) null,
fName varchar(255) null)
--将查询结果插入到表中
exec master.dbo.sp_MSforeachdb "insert into DBFileInfo (dbName,fName) select N""?"",filename from ?.dbo.sysfiles"
--后期处理,比如生成Attach数据库脚本
--第一个语句的filename序号有问题
DECLARE @dbName varchar(100),@fName varchar(255), @dbName0 varchar(100),@fileCount as tinyint
DECLARE cur CURSOR
FOR SELECT dbname,fname FROM DBFileInfo order by 1
DECLARE @count smallint
SELECT @count = 1
SELECT @fileCount = 1
OPEN cur
FETCH NEXT FROM cur INTO @dbname,@fname
select @dbName0=@dbName
print "EXEC sp_attach_db @dbname=""" +@dbname + """"
WHILE (@@fetch_status <> -1)
BEGIN
if @dbName <> @dbname0
begin
SELECT @fileCount = 1
print "go"
print "EXEC sp_attach_db @dbname=""" +@dbname + """"
print ",@filename"+ convert(varchar,@fileCount) +" = """ +rtrim(@fname) + """ "
SELECT @fileCount = @fileCount+1
end
else
begin
print ",@filename"+ convert(varchar,@fileCount) +" = """ +rtrim(@fname) +""" "
end
select @dbName0=@dbName
FETCH NEXT FROM cur INTO @dbname,@fname
SELECT @count = @count + 1
END
print @count
CLOSE cur
DEALLOCATE cur
-------------------------------------------------------------------------------------------------------------------------------------
如何迁移数据库到另一个分区
问题描述:
一台服务器,联了好几个阵列,其实可以看作不同的逻辑驱动器,就假设为c盘,d盘,e盘
sql server 2000 程序装在了c盘,数据装在了d盘
现在阵列d需要撤走,我需要把原来d盘的数据库文件挪到e盘上,数据库有100多个,一个一个手动备份恢复时间不够,而且我不知道数据库文件的路径变了以后会有什么问题(我做了试验,服务起不起来了)。
我应该如何做?
我试了一种办法,就是把d盘的所有数据库的数据文件和文件夹原封不动的拷贝到e盘,然后把d盘撤走,把e盘的盘符改为d,就可以了,但是总觉得属于歪招,所以想知道正规做法是怎么做的?
解决方法:
最省事的方法还是所谓的改盘符歪招. 这种方法也最节约时间.
正常的方法就是备份/还原(不推荐, 太慢)
或者是1楼的分离/附加, 如果只是变盘符, 可以写自动化脚本
最歪的方法是改系统表, 直接把系统表中记录的数据文件和日志文件目录改正确.(SQL Server 2005已经无法修改系统表, 所以定义这种方法是最歪的)
改系统表方法的具体实现脚本:
-- 自动迁离的脚本(自动实现分离+复制文件+附加)
-- 注意根据需要修改下面的--** 注释的部分.
-- 邹建2006.07 (引用请保留此信息)
-- 备份数目录信息和分离数据库
IF OBJECT_ID('tempdb..#') IS NOT NULL
DROP TABLE #
CREATE TABLE #(
DbName sysname,
Name sysname,
FileName nvarchar(260),
FilePath as LEFT(FileName, LEN(FileName) - CHARINDEX('/', REVERSE(FileName))))
EXEC sp_msforeachdb N'
--** 如果是所有的用户数据库都要处理, 则去掉下面两句的注释, 并且注释掉后面的两行
--IF N''?'' IN(N''master'', N''model'', N''msdb'', N''tempdb'')
--RETURN -- 只能处理用户数据库
--** 如果是处理指定的用户数据库, 则保持现状
IF N''?'' NOT IN(N''HelloWorldDB'', N''AdventureWorks'')
RETURN -- 只处理指定列表的数据库
USE [?]
INSERT #(DbName, Name, FileName)
SELECT DB_NAME(), name, RTRIM(filename) FROM sysfiles
USE master
EXEC sp_detach_db N''?''
'
-- 复制数据库文件
DECLARE @s nvarchar(4000), @D_Drive char(1)
SET @D_Drive = 'D' --** 迁移到E 盘
DECLARE tb CURSOR LOCAL
FOR
SELECT N'xcopy "' + FileName + '" "' + STUFF(FilePath, 1, 1, @D_Drive) + '/" /y'
FROM #
OPEN tb
FETCH tb INTO @s
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT(@s)
EXEC master.dbo.xp_cmdshell @s
FETCH tb INTO @s
END
CLOSE tb
DEALLOCATE tb
-- 附加数据库
DECLARE @dbname sysname
DECLARE tb CURSOR LOCAL
FOR
SELECT DISTINCT
DbName
FROM #
OPEN tb
FETCH tb INTO @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
SET @s = N'EXEC sp_attach_db ' + QUOTENAME(@dbname, N'''')
SELECT @s = @s + N',''' + STUFF(FileName, 1, 1, @D_Drive) + N''''
FROM #
WHERE DbName = @dbname
EXEC sp_executesql @s
FETCH tb INTO @dbname
END
CLOSE tb
DEALLOCATE tb
sp_MSforeachdb是SQL Server2k的Master库的未公开存储过程,其作用是遍历SQL实例下多个数据库,执行相应脚本。
比如想知道各数据库的物理文件存放路径和文件名,可以执行如下语句:
exec sp_msforeachdb "select * from ?.dbo.sysfiles"
?就是该存储过程用来替换的DB名称
对于DBA来说,迁移数据库是很经常的事情,常用的方法是停服务后拷贝mdf和ldf到目标服务器,量少时还可以手工操作,量大了就只能使用脚本,有时候一台服务器上有几十个数据库,这时下面的脚本就有了用武之地。
--首先创建接受db信息的临时表
create table DBFileInfo
( dbName varchar(100) null,
fName varchar(255) null)
--将查询结果插入到表中
exec master.dbo.sp_MSforeachdb "insert into DBFileInfo (dbName,fName) select N""?"",filename from ?.dbo.sysfiles"
--后期处理,比如生成Attach数据库脚本
--第一个语句的filename序号有问题
DECLARE @dbName varchar(100),@fName varchar(255), @dbName0 varchar(100),@fileCount as tinyint
DECLARE cur CURSOR
FOR SELECT dbname,fname FROM DBFileInfo order by 1
DECLARE @count smallint
SELECT @count = 1
SELECT @fileCount = 1
OPEN cur
FETCH NEXT FROM cur INTO @dbname,@fname
select @dbName0=@dbName
print "EXEC sp_attach_db @dbname=""" +@dbname + """"
WHILE (@@fetch_status <> -1)
BEGIN
if @dbName <> @dbname0
begin
SELECT @fileCount = 1
print "go"
print "EXEC sp_attach_db @dbname=""" +@dbname + """"
print ",@filename"+ convert(varchar,@fileCount) +" = """ +rtrim(@fname) + """ "
SELECT @fileCount = @fileCount+1
end
else
begin
print ",@filename"+ convert(varchar,@fileCount) +" = """ +rtrim(@fname) +""" "
end
select @dbName0=@dbName
FETCH NEXT FROM cur INTO @dbname,@fname
SELECT @count = @count + 1
END
print @count
CLOSE cur
DEALLOCATE cur
-------------------------------------------------------------------------------------------------------------------------------------
如何迁移数据库到另一个分区
问题描述:
一台服务器,联了好几个阵列,其实可以看作不同的逻辑驱动器,就假设为c盘,d盘,e盘
sql server 2000 程序装在了c盘,数据装在了d盘
现在阵列d需要撤走,我需要把原来d盘的数据库文件挪到e盘上,数据库有100多个,一个一个手动备份恢复时间不够,而且我不知道数据库文件的路径变了以后会有什么问题(我做了试验,服务起不起来了)。
我应该如何做?
我试了一种办法,就是把d盘的所有数据库的数据文件和文件夹原封不动的拷贝到e盘,然后把d盘撤走,把e盘的盘符改为d,就可以了,但是总觉得属于歪招,所以想知道正规做法是怎么做的?
解决方法:
最省事的方法还是所谓的改盘符歪招. 这种方法也最节约时间.
正常的方法就是备份/还原(不推荐, 太慢)
或者是1楼的分离/附加, 如果只是变盘符, 可以写自动化脚本
最歪的方法是改系统表, 直接把系统表中记录的数据文件和日志文件目录改正确.(SQL Server 2005已经无法修改系统表, 所以定义这种方法是最歪的)
改系统表方法的具体实现脚本:
-- 自动迁离的脚本(自动实现分离+复制文件+附加)
-- 注意根据需要修改下面的--** 注释的部分.
-- 邹建2006.07 (引用请保留此信息)
-- 备份数目录信息和分离数据库
IF OBJECT_ID('tempdb..#') IS NOT NULL
DROP TABLE #
CREATE TABLE #(
DbName sysname,
Name sysname,
FileName nvarchar(260),
FilePath as LEFT(FileName, LEN(FileName) - CHARINDEX('/', REVERSE(FileName))))
EXEC sp_msforeachdb N'
--** 如果是所有的用户数据库都要处理, 则去掉下面两句的注释, 并且注释掉后面的两行
--IF N''?'' IN(N''master'', N''model'', N''msdb'', N''tempdb'')
--RETURN -- 只能处理用户数据库
--** 如果是处理指定的用户数据库, 则保持现状
IF N''?'' NOT IN(N''HelloWorldDB'', N''AdventureWorks'')
RETURN -- 只处理指定列表的数据库
USE [?]
INSERT #(DbName, Name, FileName)
SELECT DB_NAME(), name, RTRIM(filename) FROM sysfiles
USE master
EXEC sp_detach_db N''?''
'
-- 复制数据库文件
DECLARE @s nvarchar(4000), @D_Drive char(1)
SET @D_Drive = 'D' --** 迁移到E 盘
DECLARE tb CURSOR LOCAL
FOR
SELECT N'xcopy "' + FileName + '" "' + STUFF(FilePath, 1, 1, @D_Drive) + '/" /y'
FROM #
OPEN tb
FETCH tb INTO @s
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT(@s)
EXEC master.dbo.xp_cmdshell @s
FETCH tb INTO @s
END
CLOSE tb
DEALLOCATE tb
-- 附加数据库
DECLARE @dbname sysname
DECLARE tb CURSOR LOCAL
FOR
SELECT DISTINCT
DbName
FROM #
OPEN tb
FETCH tb INTO @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
SET @s = N'EXEC sp_attach_db ' + QUOTENAME(@dbname, N'''')
SELECT @s = @s + N',''' + STUFF(FileName, 1, 1, @D_Drive) + N''''
FROM #
WHERE DbName = @dbname
EXEC sp_executesql @s
FETCH tb INTO @dbname
END
CLOSE tb
DEALLOCATE tb
相关文章推荐
- 详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb
- 详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb
- 详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb
- (SqlServer)不公开存储过程sp_Msforeachtable与sp_Msforeachdb详解
- (SqlServer)不公开存储过程sp_Msforeachtable与sp_Msforeachdb详解
- 详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb
- 详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb
- 系统存储过程sp_MSforeachtable和sp_MSforeachdb
- 详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb
- 微软不公开存储过程sp_Msforeachtable与sp_Msforeachdb详解-统计数据库-记录数-容量-存储过程脚本等
- 系统存储过程sp_MSforeachtable和sp_MSforeachdb
- 两个有用的,ms未公开的存储过程sp_MSforeachDB,sp_MSforeachtable
- 详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb
- 遍历数据库的未公开存储过程sp_MSforeachdb应用之Attach数据库
- 使用非正式的存储过程 sp_MSforeachdb
- 详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb
- SQL SERVERR中未公开的存储过程sp_MSforeachtable
- 不公开存储过程sp_Msforeachtable与sp_Msforeachdb详解
- sp_MSforeachdb获得所有的数据库的存储空间
- 一个值得研究的系统存储过程 sp_MSforeachtable