|
以操作系统命令行解释器的方式执行给定的命令字符串,并以文本行方式返回任何输出。授予非管理用户执行 xp_cmdshell 的权限。
+ T/ x8 Q4 }% F! n0 x ' u1 t3 c; e0 y0 j) `% {# _
说明 在 Microsoft® Windows® 98 操作系统中执行 xp_cmdshell 时,将不把 xp_cmdshell 的返回代码设置为唤醒调用的可执行文件的进程退出代码。返回代码始终为 0。* ^+ g- {6 D8 V3 r
+ o0 e1 R7 z3 q. x3 [! ~
3 v% @: e' O! p9 p语法
% k/ s" P3 v7 X* W& V% N$ Sxp_cmdshell {'command_string'} [, no_output] 8 v( n4 u& K3 ?8 Z2 d2 X% y
参数4 k7 k4 ]7 h2 H
'command_string' / p% U! w7 f5 T( S& s0 [
是在操作系统命令行解释器上执行的命令字符串。command_string 的数据类型为 varchar(8000) 或 nvarchar(4000),没有默认值。command_string 不能包含一对以上的双引号。如果由 command_string 引用的文件路径或程序名称中有空格,则需要使用一对引号。如果使用嵌入空格不方便,可考虑使用 FAT 8.3 文件名作为解决办法。 9 v L4 v% ]! t; V- b, l
no_output ' t5 k7 z7 X% i' A! R
是可选参数,表示执行给定的 command_string,但不向客户端返回任何输出。
) J8 I8 }! h. e2 q; P. h返回代码值
4 V- n8 w0 O2 m" l3 N0(成功)或 1(失败)
- S+ \3 M. U" z; `" h结果集2 V# S$ v7 _9 H- P; r0 m& |; b
执行下列 xp_cmdshell 语句将返回当前目录的目录列表。 xp_cmdshell 'dir *.exe'
3 _6 D% H- |% H
L' y3 O+ R7 Z行以 nvarchar(255) 列的形式返回。 $ M4 u6 B& g! Z: L% v" }2 |* E
执行下列 xp_cmdshell 语句将返回随后的结果集: xp_cmdshell 'dir *.exe', NO_OUTPUT
2 K6 ~* g6 v6 D) r3 e( N7 R! w, w' a# X2 @' L. e C' _
下面是结果: The command(s) completed successfully.
5 v4 M! v9 k6 Q: O% g注释# V4 V4 b. Z" M8 I& l* p% E
xp_cmdshell 以同步方式操作。在命令行解释器命令执行完毕之前,不会返回控制。
2 n) n# B% T9 p1 h$ c当授予用户执行权限时,用户能在 Microsoft Windows NT® 命令行解释器上执行运行 Microsoft SQL Server™ 的帐户有权执行的任何操作系统命令。
. F9 x3 e( @- Z. |默认情况下,只有 sysadmin 固定服务器角色的成员才能执行此扩展存储过程。但是,也可以授予其他用户执行此存储过程的权限。
" k8 S- ?( X. g当作为 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 用户的安全上下文下执行。 1 e1 O/ B- ~* \, ~; ?
" V; \+ e8 ?* F: `
说明 在早期版本中,获得 xp_cmdshell 执行权限的用户在 MSSQLServer 服务的用户帐户上下文中运行命令。可以通过配置选项配置 SQL Server,以便对 SQL Server 无 sa 访问权限的用户能够在 SQLExecutiveCmdExec Windows NT 帐户的上下文中运行 xp_cmdshell。在 SQL Server 7.0 中,该帐户称为 SQLAgentCmdExec。现在,不是 sysadmin 固定服务器角色成员的用户将在该帐户上下文中运行命令,而无需再进行配置更改。
9 F0 Z% T' A( Y3 {& {. S2 U! X& Z* v: R# e7 H. [
权限
- D5 f+ X# Z- j* r xp_deletemail 的执行权限默认授予 sysadmin 固定服务器角色的成员,但可以授予其他用户。 5 I3 K h% j. K; x& I5 I
7 c8 ? U/ h8 a3 X重要 如果为 MSSQLServer 服务选用的 Windows NT 帐户不是本地管理员组的成员,则非 sysadmin 固定服务器角色成员的用户将无法执行 xp_cmdshell。
) l8 l4 A, O9 d* D# p2 D
2 c2 I; L4 ]* {6 g3 X示例A. 返回可执行文件列表0 {& X7 e3 _5 e8 G
下例显示执行目录命令的 xp_cmdshell 扩展存储过程。 EXEC master..xp_cmdshell 'dir *.exe'
1 M$ K5 _: x, p/ @' H! x: sB. 使用 Windows NT net 命令0 |( x5 r W2 |) b3 {
下例显示 xp_cmdshell 在存储过程中的使用。下例先用 net send 通知用户 SQL Server 即将关闭,然后用 net pause 暂停服务器,最后用 net stop 关闭服务器。 CREATE PROC shutdown10
[/ ]6 i% C" t6 Y0 [( }' d3 eAS/ Q: u. S$ E. y; M) G' u; G
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down
8 C: u% M1 w. v& A2 z$ I in 10 minutes. No more connections allowed.', no_output1 ]' F r9 R, {
EXEC xp_cmdshell 'net pause sqlserver'& }2 T( Y$ q3 E4 E7 S3 N& b
WAITFOR DELAY '00:05:00', W6 u$ T! j8 q J; I4 b
EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server shutting down
5 d5 [7 s+ { Z3 \) l4 o4 ? in 5 minutes.', no_output
/ C( \. {- Z7 qWAITFOR DELAY '00:04:00'
5 Z l+ S3 m- G* u/ d: o5 CEXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down 2 E7 d) q6 Q8 X: O
in 1 minute. Log off now.', no_output
0 B& v. J4 B% L& E/ nWAITFOR DELAY '00:01:00'9 D p# p, u' h/ A2 L
EXEC xp_cmdshell 'net stop sqlserver', no_output
$ e; \3 M6 l2 f' ?C. 不返回输出 " t: A, D2 {* }) I4 _, f
下例使用 xp_cmdshell 执行命令字符串,且不向客户端返回输出。 USE master
- H1 ?- o0 H+ ]8 P, OEXEC xp_cmdshell 'copy c:\sqldumps\pubs.dmp \\server2\backups\sqldumps', 2 a6 Z2 n3 |2 U9 c1 d
NO_OUTPUT4 u; w' R p- T
D. 使用返回状态
/ P/ R& @4 ]8 ` O8 }; B' ]. Q在下例中,xp_cmdshell 扩展存储过程也给出了返回状态。返回代码值存储在变量 @result 中。 DECLARE @result int% _, B, E1 W9 \& W* H- n1 {1 s
EXEC @result = xp_cmdshell 'dir *.exe'% r* S0 q# ^6 b+ m' O) {! s
IF (@result = 0)
# Z! J" J1 I Y1 I PRINT 'Success'. K! g- V, ]/ h2 x% Q' r6 J
ELSE
|5 ] W$ K F W' [5 y: j PRINT 'Failure'
2 {0 c, Y3 W! [2 L" q7 UE. 将变量内容写入文件
/ ?8 U0 ^, t* T下例将 @var 变量的内容写入当前服务器目录下名为 var_out.txt 的文件中。 DECLARE @cmd sysname, @var sysname4 w/ x9 ^/ Z2 O- z* P0 [) z6 u! B
SET @var = 'Hello world': q! ?4 `! ~, O# T% Q" S: _
SET @cmd = 'echo ' + @var + ' > var_out.txt'
: n, l. o) @ K$ r$ h" e0 q3 vEXEC master..xp_cmdshell @cmd
/ ?/ z" l2 e2 x8 O3 o+ aF. 将命令的结果捕获到文件! O7 {$ B- y; r4 ^
下例将当前目录的内容写入当前服务器目录中名为 dir_out.txt 的文件中。 DECLARE @cmd sysname, @var sysname
. C* D0 w( X3 r4 ASET @var = 'dir/p'
: y. M a6 C3 g- x8 b8 q5 D* GSET @cmd = @var + ' > dir_out.txt'
( a$ n/ _" \1 P; e* q& LEXEC master..xp_cmdshell @cmd
! I, C5 h( o3 K9 e7 }
6 s+ d1 F4 A+ K0 l5 `
2 T# v! s' ]/ B! q3 ]9 ]8 r请参见
( S. o& `8 N( U( [- f1 y 1 K6 `7 X4 F% T1 O; v, t! d: m
sqlserver2000/tsqlref/ts_create_4hk5.htm">CREATE PROCEDURE ( j5 B, W! Z8 _' r$ m
sqlserver2000/tsqlref/ts_ea-ez_05ro.htm">EXECUTE
% [! n5 ^# c" _' f6 i# \" @% q创建安全帐户
0 O) z: ~6 o, c6 @/ F% ]sqlserver2000/tsqlref/ts_sp_00_519s.htm">系统存储过程(常规扩展过程) $ q% G) H2 p# |( Y/ W' ^
* }4 R) K1 g6 g3 M
$ C, W2 C* ?. M% q3 v. K& J. E |