【问题标题】:xp_cmdshell Query Length Too Largexp_cmdshell 查询长度太大
【发布时间】:2012-06-12 10:47:31
【问题描述】:

所有,我需要将一个大型 SQL 表中的数据集写入 .txt 文件。为此,我选择使用 xp_cmdshell。我用来创建 Data.txt 文件的查询是

declare @sql varchar(8000) 
select @sql = 'bcp "SELECT /*Lots of field names here*/ ' +
'FROM [SomeDatabase]..TableName WHERE /*Some Long Where Clause*/" ' + 
'queryout "M:\\SomeDir\\SomeOtherDirectory\\Data.txt" -c -t -T -S' + @@servername 
exec master..xp_cmdshell @sql

我遇到的问题是我使用的SELECT 查询超出了命令行强加的 1024 个字符限制。为了解决这个问题,我决定尝试使用sqlcmd 尝试从文件中执行我需要的 SQL 查询,从而消除查询长度的错误。我尝试了以下查询

DECLARE @DatabaseName VARCHAR(255)
DECLARE @cmd VARCHAR(8000)
SET @DatabaseName = 'SomeDatabase' 
SET @CMD = 'SQLCMD -E -S (localhost) -d ' + @DBName + 
    'i "M:\\SomeDir\\SomeOtherDirectory\\tmpTestQuery.sql"' 
EXEC master..xp_cmdshell @CMD 

其中 'tmpTestQuery.sql' 包含我要执行的长查询,但出现以下错误

HResult 0x2AF9, Level 16, State 1
TCP Provider: No such host is known.
NULL
Sqlcmd: Error: Microsoft SQL Server Native Client 10.0 : A network-related or instance-
    specific error has occurred while establishing a connection to SQL Server. 
    Server is not found or not accessible. Check if instance name is correct and 
    if SQL Server is configured to allow remote connections. 
    For more information see SQL Server Books Online..
Sqlcmd: Error: Microsoft SQL Server Native Client 10.0 : Login timeout expired.
NULL

我已启用远程连接。

我想知道我做错了什么,是否有其他方法可以解决我在使用 xp_cmdshell 时遇到的查询长度问题?

感谢您的宝贵时间。

注意。这个查询最终会从 C# 调用,所以计划是将很长的查询写入一个临时的 .txt 文件,使用概述的方法执行它,完成后删除。

【问题讨论】:

    标签: sql tsql xp-cmdshell


    【解决方案1】:

    绕过 BCP 限制的一种方法是将复杂查询包装在视图或存储过程中,然后让 BCP 命令查询该对象。

    您的 SQLCMD 可能由于 localhost 周围的括号而无法工作。试试:

    ...
    SET @CMD = 'SQLCMD -E -S localhost -d ' + @DBName + 
    ...
    

    【讨论】:

    • 我创建了一个包含大型选择查询的存储过程。我现在使用declare @sql varchar(8000) select @sql = 'bcp "EXEC ispsCreateDrgData;" queryout "M:\\Nhcdc\\R14TData\\DRGData.txt" -c -t -T -S' + @@servername exec master..xp_cmdshell @sql 运行它,但它无法识别我的 sp 'ispsCreateDrgData',我在这里做错了什么?
    • @Killercam - bcp 将连接到默认数据库以进行登录。尝试完全限定 SP 名称 (dbname.schemaname.ispsCreateDrgData),或者如果您使用的是 SQL 2008,请在命令行中使用 -d 标志指定数据库名称。
    • 我没有从命令行运行。我试图完全限定名称,这没有区别。您对我为什么会收到此 [通常是神秘的 SQL] 错误有任何想法吗?再次感谢您的宝贵时间。
    • @Killercam - 你能用错误信息和你正在使用的命令更新问题吗?
    • 我已经通过使用 VIEW 而不是存储过程解决了这个问题。
    【解决方案2】:

    您可以将所需数据插入到全局临时表 (##temp_table) 中,然后将其用作源:

    declare @sql varchar(8000) 
    select @sql = 'bcp "SELECT * FROM ##temp_table" ' + 
    'queryout "M:\\SomeDir\\SomeOtherDirectory\\Data.txt" -c -t -T -S' + @@servername 
    exec master..xp_cmdshell @sql
    

    【讨论】:

    • 由于数据集的剪切大小,这不是一个选项,但是,我们已经考虑写入“临时”表(非##TempTable),然后删除它。它仍然是一个可行的选择。感谢您的宝贵时间...
    猜你喜欢
    • 2013-12-21
    • 2011-06-23
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 2021-03-10
    • 1970-01-01
    相关资源
    最近更新 更多