简体   繁体   English

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

[英]using BCP to export stored procedure result in SQL Server 2008

Heyy, Heyy,

I'm trying to use BCP to export a SP result to a text file using this query: 我正在尝试使用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 '

The output of this query is telling this error: 此查询的输出告诉此错误:

Error = [Microsoft][SQL Server Native Client 10.0][SQL Server]Incorrect syntax near the keyword 'where'. 错误= [Microsoft] [SQL Server Native Client 10.0] [SQL Server]关键字“where”附近的语法不正确。

even thought I'm sure that the stored procedure "usp_Contract_SelectByEmpId" is working correctly. 甚至以为我确定存储过程“usp_Contract_SelectByEmpId”正常工作。

Anyone faced that kind of error before? 以前有人遇到过那种错误吗?

  1. As Lynn suggested, check your stored procedure. 正如Lynn建议的那样,检查你的存储过程。 It looks like the issue is within that. 看起来问题就在于此。

  2. Ensure any plain SELECT works (eg, C: drive is database server's local drive, not necessarily your own local drive). 确保任何普通的SELECT工作(例如,C:驱动器是数据库服务器的本地驱动器,不一定是您自己的本地驱动器)。

  3. If the first two items work fine, then add SET FMTONLY OFF as follows: 如果前两项工作正常,则按如下方式添加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' EXEC xp_cmdshell'bcp“设置fmtonly off exec asmary..usp_Contract_SelectByEmpId -1,1”queryout“C:\\ test.txt”-w -C OEM -t $ -T -r~ -Sheba \\ HEBADREAMNET'

I have to admit that when I tried similar on my computer it failed with 'Function sequence error', and I found that it is related to a SQL Server 2008 bug fixed in 2011. 我不得不承认,当我在计算机上尝试使用类似功能时,它会因“功能序列错误”而失败,我发现它与2011年修复的SQL Server 2008错误有关。

Please note also that even without SET FMTONLY OFF everything works with BCP library (odbcbcp.dll/odbcbcp.lib). 请注意,即使没有SET FMTONLY OFF,一切都可以使用BCP库(odbcbcp.dll / odbcbcp.lib)。 So, you can have much more generic ODBC-wide bcp solution if you write your own wrapper executable (for instance, in C or C++). 因此,如果您编写自己的包装器可执行文件(例如,在C或C ++中),则可以使用更通用的ODBC范围的bcp解决方案。

I also found the following at http://msdn.microsoft.com/en-us/library/ms162802.aspx 我还在http://msdn.microsoft.com/en-us/library/ms162802.aspx上找到了以下内容

The query can reference a stored procedure as long as all tables referenced inside the stored procedure exist prior to executing the bcp statement. 只要存储过程中引用的所有表在执行bcp语句之前存在,查询就可以引用存储过程。 For example, if the stored procedure generates a temp table, the bcp statement fails because the temp table is available only at run time and not at statement execution time. 例如,如果存储过程生成临时表,则bcp语句将失败,因为临时表仅在运行时可用,而不是在语句执行时可用。 In this case, consider inserting the results of the stored procedure into a table and then use bcp to copy the data from the table into a data file. 在这种情况下,请考虑将存储过程的结果插入表中,然后使用bcp将表中的数据复制到数据文件中。

Please see also my later separate reply - I think the whole concept of using stored procedure for BCP/queryout is wrong. 请参阅我后来的单独回复 - 我认为使用存储过程进行BCP / queryout的整个概念是错误的。

Try this. 尝试这个。

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

Sorry for flooding your question with multiple answers, but I wanted to find out how much heavier (performance-wise) the use of stored procedure is compared to plain SELECT. 很抱歉用多个答案充斥你的问题,但我想知道存储过程的使用与普通SELECT相比有多重(性能方面)。 And I got a very important information from 我从中获得了非常重要的信息

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

This forced me to create another (separate) answer. 这迫使我创建另一个(单独的)答案。 The post I refer to invalidates the whole concept. 我提到的帖子使整个概念无效。

In a few words: stored procedure might be called several (3) times in order to figure out the structure of the resultset, then the actual data. 简而言之:存储过程可能会被调用几(3)次,以便找出结果集的结构,然后是实际数据。

Therefore (and especially if calling from SQL Server connection rather than client), I think it makes a lot more sense to have a stored procedure or function, which will return SELECT statement. 因此(特别是如果从SQL Server连接而不是客户端调用),我认为有一个存储过程或函数更有意义,它将返回SELECT语句。 Then you can have another generic stored procedure or function to create and execute full BCP command with that statement embedded. 然后,您可以使用另一个通用存储过程或函数来创建并执行嵌入该语句的完整BCP命令。 I am pretty sure that in this case BCP might use a lot better execution plan. 我很确定在这种情况下BCP可能会使用更好的执行计划。 Unfortunately, I cannot verify that in practice, because of BCP bug in SQL Server 2008 R2 I mentioned in my previous post. 不幸的是,我无法在实践中验证,因为我在上一篇文章中提到过SQL Server 2008 R2中的BCP错误。

NB Please be careful creating dynamic queries and escape all explicit literal strings (ie repeat all single quotes twice) in order to avoid notorious SQL injection. 注意请小心创建动态查询并转义所有显式文字字符串(即重复所有单引号两次),以避免臭名昭着的SQL注入。 Unfortunately, there is another pitfall: you should ensure you are not escaping your queries twice or more times. 不幸的是,还有另一个陷阱:你应该确保你没有两次或多次逃避查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM