2016-05-22 3 views
0

私は以下のbcpコマンドをストアドプロシージャから持っています。次のようにストアドプロシージャが作成されます。私はこれを実行しようとするとXMLを出力するときのT-SQL bcp構文の問題

SET @sqlCmd = 'bcp "' + @sqlStr + '" queryout "' + @offersFilename + '" -w -T'; 

EXEC xp_cmdshell @sqlCmd; 

は、私は私の@sqlCmdにおけるいくつかの構文エラーがある意味、BCPの使用応答を取得します。

PRINT @ sqlCMDを使用すると、次のような出力が得られます。誰かが私が間違っているところに助言してもらえますか?ありがとう。

bcp "select custID as ""@id"", 
     (
      SELECT familyDesc as ""familyDesc"", 
       upc as ""upc"", 
       itemDesc as ""itemDescription"", 
       offerCode as ""offerCode"", 
       offerDesc as ""offerDesc"", 
       validFrom as ""validFrom"", 
       validTo as ""validTo"", 
       cast(round(price,2) as decimal(19,2)) as ""price"", 
       imageURL as ""imageURL"" 
      FROM tblCustomerOffers t2 where t1.custID=t2.custID 
      for XML PATH('Offer'), TYPE 
     ) 
     from tblCustomerOffers t1 
     group by custID 
     FOR XML PATH('Customer'), ROOT ('Offers'), ELEMENTS" 
queryout "D:\offers\customerOffers.xml" -w -T 

答えて

2

私は仕事でこれに似た問題に遭遇しました。これを簡単にデバッグを行うため

一つの方法は、代わりにBCPのqueryoutコマンドを使用するのでは、クエリの結果を格納するためにグローバル一時テーブルを作成することです。次に、bcpのを使用してその単一のレコードをエクスポートします。コマンドを実行します。例えば

CREATE TABLE ##FooResults (result XML) 
INSERT INTO ##FooResults 
SELECT (
    SELECT Bar AS [Bar] 
    FROM Foo 
    FOR XML PATH('Foo') 
) 

DECLARE @ExportXmlCommand VARCHAR(4000) = 'bcp ##FooResults out "C:\foo.xml" -w -T' 
EXEC xp_cmdshell @ExportXmlCommand 

DROP TABLE ##FooResults 

これの利点は、それはあなたがSSMSの構文強調表示の利点を活用することを可能にすると、エラーの場合は、より詳細な結果を提供することです。


欠点は、すべてのXMLが1行に縮小されていることです。

これを処理するために、XMLを再フォーマットして読みやすくするPowershellスクリプトを実行して回避策を考案しました。 (https://blogs.msdn.microsoft.com/powershell/2008/01/18/format-xml/から適応)

Param(
    [string]$infile, 
    [string]$outfile, 
    [int]$indent = 4 
) 

function Format-XML { 
    Param(
     [xml]$xml, 
     [int]$indent = 4 
    ) 
    $StringWriter = New-Object System.IO.StringWriter 
    $XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter 
    $xmlWriter.Formatting = "indented" 
    $xmlWriter.Indentation = $indent 
    $xml.WriteContentTo($XmlWriter) 
    $XmlWriter.Flush() 
    $StringWriter.Flush() 
    Write-Output $StringWriter.ToString() 
} 

$result = Format-XML ([System.Xml.XmlDocument](cat (Resolve-Path $infile))) $indent 
$result | Set-Content "$outfile" 


だから、最後の数行は次のように見て終わる、一緒にすべてを置く:

DECLARE @ExportXmlCommand VARCHAR(4000) = 'bcp ##FooResults out "C:\foo.temp.xml" -w -T' 
DECLARE @FormatXmlCommand VARCHAR(4000) = 'PowerShell.exe -ExecutionPolicy Bypass -File "C:\Format-Xml.ps1" "C:\foo.temp.xml" "C:\foo.xml"' 
DECLARE @DeleteTempXmlCommand VARCHAR(4000) = 'del "C:\foo.temp.xml"' 

EXEC xp_cmdshell @ExportXmlCommand 
EXEC xp_cmdshell @FormatXmlCommand 
EXEC xp_cmdshell @DeleteTempXmlCommand 

は、私は、これはあなたが原因を見つけることができます願っていますエラーの!

エリック

+0

どうもありがとう@Ericポーター、この回避策(グローバルTEMPおよびPowerShellスクリプトは)私は、少なくとも全体のプロセスを自動化するために、その間に実装することができる最高のソリューションです。 DOSプロンプトで上記のようにbcpコマンド全体を入力するとうまくいくので、奇妙ですが、ストアドプロシージャでラップして、すべての地獄が緩んでしまいます。どうもありがとう! – Ceasar