不用“维护计划”实现mssql定期备份并压缩存档

mssql有命令行客户端工作,可以通过bat脚本调用命令行工具执行备份命令,这样还可以很方便的调用7z,(win)rar等来自动压缩,比mssql 自带的维护计划灵活多了。“维护计划”好像也可以调用压缩工具,只是要启用xp_cmd这个很风险的存储过程,让人不安心,所以一般不这么用,备份文件都是手工压缩再下载到本地存档备份。

MS sql 的官方命令行客户端叫sqlcmd,ms sql2005默认安装的,位于 X:\Program Files\Microsoft SQL Server\90\Tools\Binn ,该目录会被自动加入windows 的PATH环境变量中,所以可以直接调用,先看看基本的帮助文档:

C:\Documents and Settings\Administrator>sqlcmd /?
Microsoft (R) SQL Server 命令行工具
版本 9.00.1399.06 NT INTEL X86
版权所有 (c) Microsoft Corporation。保留所有权利。

用法: Sqlcmd            [-U 登录 ID]          [-P 密码]
 [-S 服务器]            [-H 主机名]          [-E 可信连接]
 [-d 使用数据库名称] [-l 登录超时值]     [-t 查询超时值]
 [-h 标题]           [-s 列分隔符]      [-w 屏幕宽度]
 [-a 数据包大小]        [-e 回显输入]        [-I 允许带引号的标识符]
 [-c 命令结束]            [-L 列出服务器[清除输出]]
 [-q "命令行查询"]   [-Q "命令行查询" 并退出]
 [-m 错误级别]        [-V 严重级别]     [-W 删除尾随空格]
 [-u unicode 输出]    [-r[0|1] 发送到 stderr 的消息]
 [-i 输入文件]         [-o 输出文件]        [-z 新密码]
 [-f <代码页> | i:<代码页>[,o:<代码页>]] [-Z 新建密码并退出]
 [-k[1|2] 删除[替换]控制字符]
 [-y 可变长度类型显示宽度]
 [-Y 固定长度类型显示宽度]
 [-p[1] 打印统计信息[冒号格式]]
 [-R 使用客户端区域设置]
 [-b 出错时中止批处理]
 [-v 变量 = "值"...]  [-A 专用管理连接]
 [-X[1] 禁用命令、启动脚本、环境变量[并退出]]
 [-x 禁用变量情况]
 [-? 显示语法摘要]

C:\Documents and Settings\Administrator>

详细参数介绍可以参看这里: sql server 2005 使用命令行备份数据

一个最简单的一个命令行备份实例

C:\Documents and Settings\Administrator>sqlcmd -U sa -P sa -S localhost -Q "backup database foo to disk='f:\backup\foo_110630.bak'"
已为数据库 'foo',文件 'foo' (位于文件 1 上)处理了 5032 页。
已为数据库 'foo',文件 'foo_log' (位于文件 1 上)处理了 1 页。
BACKUP DATABASE 成功处理了 5033 页,花费 1.871 秒(22.036 MB/秒)。

一个比较完善的自动批处理脚本

一个比较完善的自动批处理脚本,可以同时备份并rar压缩多个数据库,可以按需要在此基础上修改改进。

@ECHO ON
set d=%date:~0,10%
set d=%d:-=%
set t=%time:~0,8%
set t=%t::=%
set stamp=%p%%d%%t%
set bakupfolder=F:\backup\
rem    1按子目录保存备份文件;0不按
set lay_in_subfolder=1

call :backupone foo
call :backupone foo2
call :backupone foo3
call :backupone foo4

goto :EOF  

@ECHO OFF

:backupone 
setlocal 
echo %1 
set dbname=%1
if not exist %bakupfolder%%dbname% mkdir %bakupfolder%%dbname%

if %lay_in_subfolder%==1 (
set subfolder=%dbname%\
)else set subfolder=
rem echo %bakupfolder%%subfolder%%dbname%%stamp%.bak
sqlcmd -U sa -P "sa" -S localhost -Q "backup database %dbname% to disk='%bakupfolder%%subfolder%%dbname%%stamp%.bak'"
"C:\Program Files\WinRAR\RAR.exe" a -ep1 -r -o+ -m5 -s -df "%bakupfolder%%subfolder%%dbname%%stamp%".rar "%bakupfolder%%subfolder%%dbname%%stamp%.bak"

endlocal&goto :EOF

脚本说明

1. set bakupfolder=F:\backup\

备份文件存放于目录F:\backup\ (此目录需要事先建好)

2. 默认每个数据库放置到bakupfolder下的同名的子目录(脚本自动创建)中;设置lay_in_subfolder=0后,将直接放置到bakupfolder

3. 备份文件名中自动添加备份时的时间字符串,不用担心备份目录下名字重复,也便于管理。

4. call :backupone foo

foo是需要备份的数据库,需要备份其它数据库,按同样的方式一行写一条即可

这是在批处理里中调用自定义函数

5. 命令行驱动备份操作:sqlcmd -U sa -P "sa" -S localhost -Q "xxx"

这里连接数据库的用户名密码都是sa,请改成你的实际用户名密码。mssql密码中如果有一些特殊字符,可能报错,所以加上双引号。如果密码简单,不加也可以;不过sa密码,一般都是很变态的吧~~

备份脚本的调用

加到windows计划任务里,定期执行,是一个很好的主意。

上面脚本里,只对mssql数据库执行了备份的操作,如果加入整理索引碎片、重建索引等维护操作,也是很好的自动化维护方案。

这样处理,就可以弃用mssql自带的“维护计划”了。

------ 在windows2008下使用请参阅如下 ---- 20130723 补------------

windows 2008的命令行下,date输出的日期,默认使用/作为分隔符,这样上面的脚本就不行了,要把第三行 set d=%d:-=% 作下修改:

set d=%d:/=%

其它不用变。

ms sql server 2005维护计划(备份)失败:应用于目标服务器 对于 xx 失败

ms sql server 2005维护计划(备份)失败:应用于目标服务器 对于 xx 失败,消息如下

应用于目标服务器 对于 xx 失败

ms sql server 2005维护计划(备份)失败:应用于目标服务器 对于 xx 失败

而这个错误,又没有详细的说明,为什么失败,失败在哪里;不说明详细原因,这也是微软的产品经常让人很崩溃的重要原因之一。

网上也有人遇到这这种问题,只是找了个遍也都没有看到解决方法;不知道是否重启一下windows会不会好,但因为是生产环境的服务器,不便于重启。

突然想起命令行,命令行工具!mssql有命令行客户端工作,只是没有用过,应该可以通过bat脚本调用命令行工具执行备份命令,这样还可以很方便的调用7z,(win)rar等来自动压缩,比mssql 自带的维护计划灵活多了。“维护计划”好像也可以调用压缩工具,只是要启用xp_cmd这个很风险的存储过程,让人不安心,所以一般不这么用,备份文件都是手工压缩再下载到本地存档备份。

MS sql 的官方命令行客户端叫sqlcmd,ms sql2005默认安装的,位于 X:\Program Files\Microsoft SQL Server\90\Tools\Binn ,该目录会被自动加入windows 的PATH环境变量中,所以可以直接调用,先看看基本的帮助文档:

C:\Documents and Settings\Administrator>sqlcmd /?
Microsoft (R) SQL Server 命令行工具
版本 9.00.1399.06 NT INTEL X86
版权所有 (c) Microsoft Corporation。保留所有权利。

用法: Sqlcmd            [-U 登录 ID]          [-P 密码]
 [-S 服务器]            [-H 主机名]          [-E 可信连接]
 [-d 使用数据库名称] [-l 登录超时值]     [-t 查询超时值]
 [-h 标题]           [-s 列分隔符]      [-w 屏幕宽度]
 [-a 数据包大小]        [-e 回显输入]        [-I 允许带引号的标识符]
 [-c 命令结束]            [-L 列出服务器[清除输出]]
 [-q "命令行查询"]   [-Q "命令行查询" 并退出]
 [-m 错误级别]        [-V 严重级别]     [-W 删除尾随空格]
 [-u unicode 输出]    [-r[0|1] 发送到 stderr 的消息]
 [-i 输入文件]         [-o 输出文件]        [-z 新密码]
 [-f <代码页> | i:<代码页>[,o:<代码页>]] [-Z 新建密码并退出]
 [-k[1|2] 删除[替换]控制字符]
 [-y 可变长度类型显示宽度]
 [-Y 固定长度类型显示宽度]
 [-p[1] 打印统计信息[冒号格式]]
 [-R 使用客户端区域设置]
 [-b 出错时中止批处理]
 [-v 变量 = "值"...]  [-A 专用管理连接]
 [-X[1] 禁用命令、启动脚本、环境变量[并退出]]
 [-x 禁用变量情况]
 [-? 显示语法摘要]

C:\Documents and Settings\Administrator>

详细参数介绍可以参看这里: sql server 2005 使用命令行备份数据

一个最简单的一个命令行备份实例

C:\Documents and Settings\Administrator>sqlcmd -U sa -P sa -S localhost -Q "backup database foo to disk='f:\backup\foo_110630.bak'"
已为数据库 'foo',文件 'foo' (位于文件 1 上)处理了 5032 页。
已为数据库 'foo',文件 'foo_log' (位于文件 1 上)处理了 1 页。
BACKUP DATABASE 成功处理了 5033 页,花费 1.871 秒(22.036 MB/秒)。

一个比较完善的自动批处理脚本

一个比较完善的自动批处理脚本,可以同时备份并rar压缩多个数据库,可以按需要在此基础上修改改进。

@ECHO ON
set d=%date:~0,10%
set d=%d:-=%
set t=%time:~0,8%
set t=%t::=%
set stamp=%p%%d%%t%
set bakupfolder=F:\backup\
rem    1按子目录保存备份文件;0不按
set lay_in_subfolder=1

call :backupone foo
call :backupone foo2
call :backupone foo3
call :backupone foo4

goto :EOF  

@ECHO OFF

:backupone 
setlocal 
echo %1 
set dbname=%1
if not exist %bakupfolder%%dbname% mkdir %bakupfolder%%dbname%

if %lay_in_subfolder%==1 (
set subfolder=%dbname%\
)else set subfolder=
rem echo %bakupfolder%%subfolder%%dbname%%stamp%.bak
sqlcmd -U sa -P "sa" -S localhost -Q "backup database %dbname% to disk='%bakupfolder%%subfolder%%dbname%%stamp%.bak'"
"C:\Program Files\WinRAR\RAR.exe" a -ep1 -r -o+ -m5 -s -df "%bakupfolder%%subfolder%%dbname%%stamp%".rar "%bakupfolder%%subfolder%%dbname%%stamp%.bak"

endlocal&goto :EOF

脚本说明

1. set bakupfolder=F:\backup\

备份文件存放于目录F:\backup\ (此目录需要事先建好)

2. 默认每个数据库放置到bakupfolder下的同名的子目录(脚本自动创建)中;设置lay_in_subfolder=0后,将直接放置到bakupfolder

3. 备份文件名中自动添加备份时的时间字符串,不用担心备份目录下名字重复,也便于管理。

4. call :backupone foo

foo是需要备份的数据库,需要备份其它数据库,按同样的方式一行写一条即可

这是在批处理里中调用自定义函数

5. 命令行驱动备份操作:sqlcmd -U sa -P "sa" -S localhost -Q "xxx"

这里连接数据库的用户名密码都是sa,请改成你的实际用户名密码。mssql密码中如果有一些特殊字符,可能报错,所以加上双引号。如果密码简单,不加也可以;不过sa密码,一般都是很变态的吧~~

备份脚本的调用

加到windows计划任务里,定期执行,是一个很好的主意。

上面脚本里,只对mssql数据库执行了备份的操作,如果加入整理索引碎片、重建索引等维护操作,也是很好的自动化维护方案。

这样处理,就可以弃用mssql自带的“维护计划”了。

sql server 启用xp_cmdshell 重启pcanywhere

windows2003服务器使用pcanywhere进行远程管理,但有时pcanywhere会出问题而服务关闭,因为服务器在电信机房,以前这种问题只能请机房工作人员直接reset服务器,但这不是个好办法,直接reset断电,对数据而言,是很不安全的,不出问题则已,出问题就严重了。所以最好还是通过软件启动。
但问题是,windows无法登录,于是悖论了...
考虑到该服务器上装有ms sql server,而且启用了远程sa用户登录,于是想到了借用xp_cmdshell重新启动pcanywhere服务awhost32。
默认状态下xp_cmdshell是关闭状态的,需要通过sa帐号登录mssql,启用xp_cmdshell,以命令行形式开启awhost32服务,再关闭xp_cmdshell.
如下:

开启xp_cmdshell

EXEC sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'show advanced options', 0

开启awhost32服务

xp_cmdshell 'net start awhost32'

关闭xp_cmdshell

EXEC sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'xp_cmdshell', 0
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'show advanced options', 0

完成!

如何将MS SQL数据库设置为单用户模式

提问:
如何将数据库设置为单用户模式,并将访问限制为只供 dbo 使用?解答:

在 sql server 2000 中,数据库不能同时为单用户模式和只供 dbo 使用模式。而以下可选选项可以通过使用 alter database 命令来使用:
alter database database set single_user。
该命令限制用户只能逐个访问数据库。

alter database database set restricted_user。
该命令限制只有 db_owner、dbcreator 或 sysadmin 角色的成员才能访问数据库。

alter database database set multi_user。
该命令将数据库的访问权限返回其一般运行状态。

MS SQL SERVER 孤立用户问题

Windows环境下,经常遇到系统Over的情况,如果你在新装了系统和SQL Server 2005后,需要把SQL Server2000数据库还原,就会出现孤立用户的问题,下文中我们将介绍具体的解决方法:

解决步骤如下:

1.首先,需要还原数据库。 feedom.net

2.在 安全性/登陆名/新建登陆名,把产生的孤立用户新建一个,密码什么都设置好。

3.最后在查询分析器中执行

exec sp_change_users_login 'update_one','没有登陆名的数据库用户','新的登陆名'

-----------

检测当前数据库的孤立用户

sp_change_users_login @Action='Report';

MS SQL server 自定义函数:获取汉字拼音首字母(音序)

转来的,很好用,要谢谢作者的

Create function [dbo].[fun_getPY]
(
    @str nvarchar(4000)
)
returns nvarchar(4000)
as
begin
declare @word nchar(1),@PY nvarchar(4000)

set @PY=''

while len(@str)>0
begin
    set @word=left(@str,1)

    --如果非汉字字符,返回原字符
    set @PY=@PY+(case when unicode(@word) between 19968 and 19968+20901
               then (
                    select top 1 PY
                    from
                    (
                     select 'A' as PY,N'驁' as word
                     union all select 'B',N'簿'
                     union all select 'C',N'錯'
                     union all select 'D',N'鵽'
                     union all select 'E',N'樲'
                     union all select 'F',N'鰒'
                     union all select 'G',N'腂'
                     union all select 'H',N'夻'
                     union all select 'J',N'攈'
                     union all select 'K',N'穒'
                     union all select 'L',N'鱳'
                     union all select 'M',N'旀'
                     union all select 'N',N'桛'
                     union all select 'O',N'漚'
                     union all select 'P',N'曝'
                     union all select 'Q',N'囕'
                     union all select 'R',N'鶸'
                     union all select 'S',N'蜶'
                     union all select 'T',N'籜'
                     union all select 'W',N'鶩'
                     union all select 'X',N'鑂'
                     union all select 'Y',N'韻'
                     union all select 'Z',N'咗'
                      ) T
                   where word>=@word collate Chinese_PRC_CS_AS_KS_WS
                   order by PY ASC
                          )
                      else @word
                 end)
    set @str=right(@str,len(@str)-1)
end

return @PY

end