xp_cmdshell的单行替代方案?我尝试了几件事

时间:2012-04-07 17:59:57

标签: sql sql-server sql-server-2008 tsql sql-server-2000

Hello SQL Server Masters,

好吧,我有一个如下所述的Microsoft SQL Server 2000:

Microsoft SQL Server  2000 - 8.00.2039 (Intel X86) 
May  3 2005 23:18:38 
Copyright (c) 1988-2003 Microsoft Corporation
Desktop Engine on Windows NT 5.2 (Build 3790: Service Pack 2)

我需要从这个Microsoft SQL Server执行一个操作系统命令,我检查了我对下面的查询有sysadmin权限,它返回“1”,这证实了我的特权。

SELECT IS_SRVROLEMEMBER('sysadmin', 'sa');

我尝试了传统的xp_cmdshell并没有发生任何事情,只是为了确保它正常工作我尝试了这个着名的:

EXEC xp_cmdshell 'dir c:\'; EXEC master.dbo.xp_cmdshell 'dir c:\';
EXEC master..xp_cmdshell "dir c:\";

所有返回NOTHING,这让我相信xp_cmdshell不可用。我知道xp_cmdshell在Microsoft SQL Server 2005中默认禁用,但在2000年没有,无论如何,我试图以相同的方式重新启用它但它失败了。

我查看了互联网,我发现这种方法可以为Microsoft SQL Server 2000重新启用xp_cmdshell:

exec sp_addextendedproc 'xp_cmdshell', 'xplog70.dll'

exec sp_addextendedproc xp_cmdshell, 'C:\Program Files\Microsoft SQL Server\MSSQL\Binn\xplog70.dll'

然而,它仍然无效。我发现另一篇文章说有时管理员会删除这些文件,我认为这可能是我的情况,文章说如果它被删除我可以执行“xp_msver”,在我的情况下它也不会返回任何内容。

参考:http://support.microsoft.com/kb/891984

我也尝试过在互联网上找到的这个查询,看看xp_cmdshell是否存在而且它什么都没有返回(但它可能是我奇怪的SQL客户端的限制,请参见下文)。

if exists (select * from dbo.sysobjects where id = object_id(N’[dbo].[ xp_cmdshell]‘) and OBJECTPROPERTY(id, N’IsExtendedProc’) = 1);

所以,我真的遇到了麻烦,我在谷歌研究并找到了可能的解决方案,如Job代理,SSIS包,CLR存储过程,sp_OACreate(以及朋友)和SQLCMD,但没有任何效果。也许我做错了,但我的另一个限制是我只能从跳转框(Linux)访问这个Microsoft SQL Server 2000,它有一个非常奇怪的sql-server客户端,不接受多行查询,因此,我不能尝试以下潜在的解决方案:

1#Job Agent

DECLARE @jobID uniqueidentifier, @cmd varchar(1000) 

SET @cmd = 'netstat -na > c:\connections.txt'

EXEC msdb.dbo.sp_add_job @job_name = '_tmp_MakeDirectory', @enabled  = 1, @start_step_id = 1, @owner_login_name='sa', @job_id = @jobID OUTPUT 

EXEC msdb.dbo.sp_add_jobstep @job_id = @jobID, @step_name = 'Create Backup Folder', @step_id = 1, @subsystem = 'CMDEXEC', @command = @cmd

EXEC msdb.dbo.sp_add_jobserver @job_id = @jobID

EXEC msdb.dbo.sp_start_job @job_id = @jobID, @output_flag = 0 

WAITFOR DELAY '000:00:05' -- Give the job a chance to complete

IF EXISTS (SELECT name FROM msdb.dbo.sysjobs WHERE name = '_tmp_MakeDirectory')
BEGIN
     EXEC msdb.dbo.sp_delete_job @job_name = '_tmp_MakeDirectory'
END

2#SQLCMD

CREATE PROCEDURE SQLCMD_TEST
AS
    !!MKDIR "netstat -na > c:\connections.txt"
    :OUT "C:\TEST\test.TXT"
    SELECT @@VERSION AS 'SERVER VERSION'
    !!DIR
GO
    SELECT @@SERVERNAME AS 'SERVER NAME'
GO 


EXEC SQLCMD_TEST

不幸的是我没有任何其他方式来访问这个Microsoft SQL Server,我知道这不是最好的方式,但它是如何做到的,我什么也做不了。因此,我需要一个解决方案来执行此Microsoft SQL Server 2000上的操作系统命令,并具有所有这些限制。有人可以将上述两种方法中的任何一种移植到单行查询中吗?

非常欢迎任何其他有关示例的建议。

非常感谢。

问候。

1 个答案:

答案 0 :(得分:1)

我曾经在使用CLR支持之前使用xp_cmdshell。不幸的是,您是远离CLR支持(SQL Server 2005)和system.io命名空间的版本。但是,您可以创建自己的扩展存储过程,这些过程可以访问文件系统并创建目录。有关详细信息,请参阅此处:http://www.devarticles.com/c/a/SQL-Server/Extended-Stored-Procedures-Intro-And-10-Cool-Examples/

顺便说一句,xp_cmdshell是一个扩展存储过程。