1

嘿嘿,

我正在尝试使用 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”工作正常。

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

4

3 回答 3

3
  1. 正如 Lynn 建议的那样,检查您的存储过程。看起来问题就在其中。

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

  3. 如果前两项工作正常,则添加 SET FMTONLY OFF,如下所示:

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

我不得不承认,当我在我的计算机上尝试类似的操作时,它因“功能序列错误”而失败,我发现它与 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 的整个概念是错误的。

于 2012-10-25T03:28:49.233 回答
1

尝试这个。

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
于 2012-08-09T22:31:46.360 回答
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 错误,我无法在实践中验证这一点。

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

于 2012-10-25T04:18:37.443 回答