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. 最初の 2 つの項目が正常に機能する場合は、次のように 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/クエリアウトにストアドプロシージャを使用するという概念全体が間違っていると思います。

于 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 インジェクションを回避するために、動的クエリの作成には注意し、すべての明示的なリテラル文字列をエスケープします (つまり、すべての一重引用符を 2 回繰り返す)。残念ながら、別の落とし穴があります。クエリを 2 回以上エスケープしていないことを確認する必要があります。

于 2012-10-25T04:18:37.443 に答える