|
以操作系统命令行解释器的方式执行给定的命令字符串,并以文本行方式返回任何输出。授予非管理用户执行 xp_cmdshell 的权限。 1 E1 |+ x& y; `8 V
4 P4 v* E: j) p# j$ L v
说明 在 Microsoft® Windows® 98 操作系统中执行 xp_cmdshell 时,将不把 xp_cmdshell 的返回代码设置为唤醒调用的可执行文件的进程退出代码。返回代码始终为 0。
4 \. z4 N! A- |/ v* b' N6 B: W" a+ i- C
* v9 S+ P) [3 P" L; d+ L
语法
* {; d ^# h8 X2 o* n2 I9 Ixp_cmdshell {'command_string'} [, no_output]
! H, {( X( A& a7 n" L1 \参数
" Z) a j' g" u, E'command_string'
, b+ D* N& L7 E5 e8 {9 Q是在操作系统命令行解释器上执行的命令字符串。command_string 的数据类型为 varchar(8000) 或 nvarchar(4000),没有默认值。command_string 不能包含一对以上的双引号。如果由 command_string 引用的文件路径或程序名称中有空格,则需要使用一对引号。如果使用嵌入空格不方便,可考虑使用 FAT 8.3 文件名作为解决办法。 % I- M7 `$ ~6 m
no_output 2 d5 m, A6 V; a
是可选参数,表示执行给定的 command_string,但不向客户端返回任何输出。 + P( U: R$ r5 j# Q9 T0 k
返回代码值1 T5 ]4 T0 G' N7 h3 ]+ H# _& o2 C
0(成功)或 1(失败)
2 x4 b3 r/ l4 T9 z' P E结果集 E6 m8 b! n2 C
执行下列 xp_cmdshell 语句将返回当前目录的目录列表。 xp_cmdshell 'dir *.exe'
# v. Z& Y1 C8 j6 |% B/ K2 o1 A* R1 u7 I# ^$ m
行以 nvarchar(255) 列的形式返回。
g0 t0 y- I: ]( x# C5 d执行下列 xp_cmdshell 语句将返回随后的结果集: xp_cmdshell 'dir *.exe', NO_OUTPUT
) q5 `' G" O' e# c' r1 ?! X/ b$ r) R4 i# c, r- F$ D
下面是结果: The command(s) completed successfully.4 i7 s4 F- U+ o% n/ s* J6 ^
注释
2 k2 x3 i, d7 v+ k7 zxp_cmdshell 以同步方式操作。在命令行解释器命令执行完毕之前,不会返回控制。
$ O f; l$ x1 D0 L3 r当授予用户执行权限时,用户能在 Microsoft Windows NT® 命令行解释器上执行运行 Microsoft SQL Server™ 的帐户有权执行的任何操作系统命令。 & p$ {$ N# d. T. g/ U8 ]& w+ U
默认情况下,只有 sysadmin 固定服务器角色的成员才能执行此扩展存储过程。但是,也可以授予其他用户执行此存储过程的权限。 ' Y: H. W. C$ z
当作为 sysadmin 固定服务器角色成员的用户唤醒调用 xp_cmdshell 时,将在运行 SQL Server 服务的安全上下文中执行 xp_cmdshell。当用户不是 sysadmin 组的成员时,xp_cmdshell 将模拟使用 xp_sqlagent_proxy_account 指定的 SQL Server 代理程序的代理帐户。如果代理帐户不能用,则 xp_cmdshell 将失败。这只是针对于 Microsoft® Windows NT® 4.0 和 Windows 2000。在 Windows 9.x 上,没有模拟,且 xp_cmdshell 始终在启动 SQL Server 的 Windows 9.x 用户的安全上下文下执行。 6 _0 K, l8 M) X8 z$ ]* L
; t/ g5 L( u. O& f1 \$ T8 P: N( d
说明 在早期版本中,获得 xp_cmdshell 执行权限的用户在 MSSQLServer 服务的用户帐户上下文中运行命令。可以通过配置选项配置 SQL Server,以便对 SQL Server 无 sa 访问权限的用户能够在 SQLExecutiveCmdExec Windows NT 帐户的上下文中运行 xp_cmdshell。在 SQL Server 7.0 中,该帐户称为 SQLAgentCmdExec。现在,不是 sysadmin 固定服务器角色成员的用户将在该帐户上下文中运行命令,而无需再进行配置更改。7 Y7 C8 o( A! G
* z4 l! A) u9 u0 V( Z* P
权限! h' ?) t, c6 m W* B9 [( R
xp_deletemail 的执行权限默认授予 sysadmin 固定服务器角色的成员,但可以授予其他用户。 6 _% L5 f: h+ A9 h" l
( B' Q D# ?6 k6 X6 t
重要 如果为 MSSQLServer 服务选用的 Windows NT 帐户不是本地管理员组的成员,则非 sysadmin 固定服务器角色成员的用户将无法执行 xp_cmdshell。
9 _, L/ @* q, P
6 I; a& }# W! T8 ?示例A. 返回可执行文件列表
9 J" R% J# q3 ?* m) u! i3 _ 下例显示执行目录命令的 xp_cmdshell 扩展存储过程。 EXEC master..xp_cmdshell 'dir *.exe'' n) w; _; A" x, Y1 Q6 ]- X
B. 使用 Windows NT net 命令1 \2 B4 ^' e) Y$ Z F: {* n
下例显示 xp_cmdshell 在存储过程中的使用。下例先用 net send 通知用户 SQL Server 即将关闭,然后用 net pause 暂停服务器,最后用 net stop 关闭服务器。 CREATE PROC shutdown10' N5 `6 Z3 M& R
AS
! k& d) g0 l4 L4 J; r: q: jEXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down 8 V5 |" r4 u) ? U* h1 R
in 10 minutes. No more connections allowed.', no_output
2 @- Z) A$ U0 j5 B' xEXEC xp_cmdshell 'net pause sqlserver'6 C$ g2 y& Z A g) J4 S
WAITFOR DELAY '00:05:00'( N7 a$ j! a1 u; p- h
EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server shutting down
^! v. ?$ A* G$ R d in 5 minutes.', no_output9 z/ U+ d% r# d% A2 o
WAITFOR DELAY '00:04:00'
; z* j3 u0 X$ z# N0 ]6 }; PEXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down
2 v7 I: s0 j; \ in 1 minute. Log off now.', no_output9 g# |8 f9 M7 A& M" x- m
WAITFOR DELAY '00:01:00'
; T9 t8 {6 n9 D5 r( SEXEC xp_cmdshell 'net stop sqlserver', no_output6 |6 v$ \2 q, d
C. 不返回输出
: o6 D+ {8 R& L( ~* ]. _# ]下例使用 xp_cmdshell 执行命令字符串,且不向客户端返回输出。 USE master. s# J J4 T1 o- {% [( {% N; H
EXEC xp_cmdshell 'copy c:\sqldumps\pubs.dmp \\server2\backups\sqldumps',
6 b( ?* {' V+ ~; H8 D% p NO_OUTPUT8 k+ w; D: M# N7 @- {( F6 ]
D. 使用返回状态
$ }. X; `3 K- \在下例中,xp_cmdshell 扩展存储过程也给出了返回状态。返回代码值存储在变量 @result 中。 DECLARE @result int
; w& U. j6 T2 G' r8 p: WEXEC @result = xp_cmdshell 'dir *.exe'- T1 v. j# |# G1 z
IF (@result = 0)
8 ?* H( ]5 b4 a7 s5 d( z& s PRINT 'Success'5 p( v/ p/ u$ @: P8 d& m
ELSE
/ a* P' `) H5 [ PRINT 'Failure'
) F4 w# a* X4 R# o7 pE. 将变量内容写入文件
1 `: w4 u N( S |1 x7 q下例将 @var 变量的内容写入当前服务器目录下名为 var_out.txt 的文件中。 DECLARE @cmd sysname, @var sysname" }/ `* u5 N7 N: _
SET @var = 'Hello world'
+ f# `" @( i* fSET @cmd = 'echo ' + @var + ' > var_out.txt'0 m4 v d( o3 ~0 k5 {" w
EXEC master..xp_cmdshell @cmd
- }: H* T9 c; m5 Q0 TF. 将命令的结果捕获到文件
5 @1 i) ?9 W1 L3 W, s下例将当前目录的内容写入当前服务器目录中名为 dir_out.txt 的文件中。 DECLARE @cmd sysname, @var sysname
: P% _3 |) Q7 x4 `1 s) Q7 `' c: kSET @var = 'dir/p'+ k+ W2 i% X: N& G) z
SET @cmd = @var + ' > dir_out.txt'& ~0 ~$ ]) F7 p1 c2 w
EXEC master..xp_cmdshell @cmd3 m5 H: r+ A1 \! {1 D0 P
2 N7 F/ O( G3 j. w3 D$ }$ Q# U
% w ?4 C; S) w
请参见
- @( x) r/ x- H9 a; v9 V
- W$ N! {7 F& K x sqlserver2000/tsqlref/ts_create_4hk5.htm">CREATE PROCEDURE ( m, p) A% ]' \" g
sqlserver2000/tsqlref/ts_ea-ez_05ro.htm">EXECUTE " E; {# l2 P" k. D6 f2 `& Y
创建安全帐户 , o: Y" n/ r- a
sqlserver2000/tsqlref/ts_sp_00_519s.htm">系统存储过程(常规扩展过程)
" z* ~4 D/ n3 k, w. a+ m9 x$ m. N$ M* k( l4 q J$ m9 F v* R
' ]2 j! [. L! t& Q& n3 w. g |