使用BCP导出SQL Server 2008中的存储过程结果

时间:2012-06-19 06:13:14

标签: sql bcp xp-cmdshell

Heyy,

我正在尝试使用BCP将SP结果导出到使用此查询的文本文件中:

EXEC xp_cmdshell 'bcp "exec asmary..usp_Contract_SelectByEmpId -1,1" queryout "C:\test.txt" -w -C OEM -t$ -T -r ~ -S heba\HEBADREAMNET '

此查询的输出告诉此错误:

  

错误= [Microsoft] [SQL Server Native Client 10.0] [SQL Server]关键字“where”附近的语法不正确。

甚至认为我确定存储过程“usp_Contract_SelectByEmpId”正常工作。

之前有人遇到过这种错误吗?

3 个答案:

答案 0 :(得分:3)

  1. 正如Lynn建议的那样,检查一下您的存储过程。看起来问题就在于此。

  2. 确保任何普通的SELECT工作(例如,C:驱动器是数据库服务器的本地驱动器,不一定是您自己的本地驱动器)。

  3. 如果前两项工作正常,则按以下方式添加SET FMTONLY OFF:

  4. EXEC xp_cmdshell'bcp“set fmtonly off exec asmary..usp_Contract_SelectByEmpId -1,1”queryout“C:\ test.txt”-w -C OEM -t $ -T -r~ -Sheba \ HEBADREAMNET'< / p>

    我不得不承认,当我在计算机上尝试使用类似功能时,它的“功能序列错误”失败了,我发现它与2011年修复的SQL Server 2008错误有关。

    请注意,即使没有SET FMTONLY OFF,一切都可以使用BCP库(odbcbcp.dll / odbcbcp.lib)。因此,如果您编写自己的包装器可执行文件(例如,在C或C ++中),则可以使用更通用的ODBC范围的bcp解决方案。

    我还在http://msdn.microsoft.com/en-us/library/ms162802.aspx

    找到了以下内容

    只要存储过程中引用的所有表在执行bcp语句之前存在,查询就可以引用存储过程。例如,如果存储过程生成临时表,则bcp语句将失败,因为临时表仅在运行时可用,而不是在语句执行时可用。在这种情况下,请考虑将存储过程的结果插入表中,然后使用bcp将表中的数据复制到数据文件中。

    请参阅我后来的单独回复 - 我认为使用存储过程进行BCP / queryout的整个概念是错误的。

答案 1 :(得分:0)

试试这个。

DECLARE @strbcpcmd NVARCHAR(max)
SET @strbcpcmd = 'bcp  "EXEC asmary..usp_Contract_SelectByEmpId -1,1" queryout "C:\test.txt" -w -C OEM -t"$" -T -S'+@@servername    
EXEC master..xp_cmdshell @strbcpcmd

答案 2 :(得分:0)

很抱歉用多个答案充斥您的问题,但我想知道存储过程的使用与普通SELECT相比有多重(性能方面)。我从

获得了非常重要的信息

http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/b8340289-7d7e-4a8d-b570-bec7a0d73ead/

这迫使我创建另一个(单独的)答案。我提到的帖子使整个概念无效。

简而言之:存储过程可能被调用几(3)次,以便找出结果集的结构,然后是实际数据。

因此(特别是如果从SQL Server连接而不是客户端调用),我认为拥有一个存储过程或函数会更有意义,它将返回SELECT语句。然后,您可以使用另一个通用存储过程或函数来创建并执行嵌入该语句的完整BCP命令。我很确定在这种情况下BCP可能会使用更好的执行计划。不幸的是,我无法在实践中验证,因为我在上一篇文章中提到过SQL Server 2008 R2中的BCP错误。

N.B。请小心创建动态查询并转义所有显式文字字符串(即重复所有单引号两次),以避免臭名昭着的SQL注入。不幸的是,还有另一个陷阱:你应该确保你没有两次或多次逃避查询。