创建XML,使用批量复制导出

时间:2018-02-20 11:49:43

标签: sql-server bcp sqlxml

我认为有一些独特的东西'使用bcp与FOR XML和CTE一起使用。 (也许不是?)

  

如何导出我创建动态的XML?   如果我的查询实现CTE,如果我使用WITH NAMESPACES?

,如何使用bcp      

我应该包装'命名空间和CTE周围的bcp?我应该单独创建它然后连接?   我试了一下,但似乎没什么用。

我的尝试(当然bcp select在同一行):

 ... Ansi nulls,quoted ident,created procedure,declared all variables
IF (@tabelaTipaRacuna = 'istdev')
BEGIN
SELECT @SQL = 

         'WITH XMLNAMESPACES(DEFAULT ''ba.cbbh.crr.retail''), Ent_Posta
            AS
        (
           SELECT e.naziv,p.posta,e.sifra
            FROM entitet AS e
          INNER JOIN poste AS p ON e.sifra = p.entitet
        )


          ''bcp "SELECT [dbo].[brojracuna](' + @kodBanke + ',i.partija) AS ''AccountNo/BBAN'',
           [dbo].[GENERATEIBAN](i.partija) AS ''AccountNo/IBAN'', 
           ' + '''D''' + ' AS ''AccountType'',
           (a.ime + ''('' + a.roditel + '')''  + a.prezime) AS ''Name'',
           a.embg AS ''UID'',
       CASE status 
       WHEN 2 THEN ''A'' 
       WHEN 4 THEN ''B''
       WHEN 8 THEN ''U''
  END AS ''Status'',
  c.sifra AS ''Territory'',
  ' + @kodBanke + ' as ''ID_Bank'',
  CONVERT(DATETIME,' + 'i.dotvoranje' + ',120) AS ''OpeningDate'',
  ISNULL(CONVERT(DATETIME,' + '1' + ',120),'''') AS ''ClosingDate''
 FROM adresar AS a
  INNER JOIN' + QUOTENAME(@tabelaTipaRacuna) + ' AS i 
      ON a.embg = i.embg
        INNER JOIN Ent_Posta as c
        ON a.postbroj = c.posta 
        FOR XML PATH(''Account''), ROOT(''Accounts'')"' + 'queryout' + @output + ' -c -C65001 -t";" -r"\n" -T -S' + @server;

        exec master..xp_cmdshell @sql
END

程序电话:

EXEC [dbo].[generateXML_CRR] @tabelaTipaRacuna = istdev, @output = 
     '//111.11.11.111/share/CRR.txt', @server = '111.11.11.112' 

编辑:

我试着这样说: enter image description here ...

enter image description here

但现在我在其中一张桌子上收到了无效的对象名称。

我希望我的问题看起来不会模糊,如果是的话,请要求澄清。

打印@SQL不会表示任何语法错误。

1 个答案:

答案 0 :(得分:0)

我宁愿将这些XML插入临时表并从那里执行BCP。但你的问题也可以解决......

我认为我的魔法球是正确的。它告诉我,你需要帮助如何将FOR XML的结果赋予变量以及如何从动态创建的代码中返回变量值。看看这个:

如果陈述的结果是标量,您可以直接在SELECT内分配;

DECLARE @SomeName VARCHAR(MAX);
SELECT TOP 1 @SomeName=name FROM sys.objects;
SELECT @SomeName;

您可以通过将FOR XML包装在paranthesis中来分配SELECT的结果(与简单的标量值相同):

DECLARE @myXML XML=
(SELECT * FROM sys.objects FOR XML PATH('row'),ROOT('root'));
SELECT @myXML;

这不适用于这样的语句,因为WITH不允许嵌入:

WITH FilterObjects AS
(SELECT * FROM sys.objects WHERE name LIKE '%row%')
SELECT * 
FROM FilterObjects
FOR XML PATH('row'),ROOT('root');

但你可以混合两种方法:

DECLARE @myXML2 XML;

WITH FilterObjects AS
(SELECT * FROM sys.objects WHERE name LIKE '%row%')
SELECT @myXML2=
( --wrap this and assign it
    SELECT * 
    FROM FilterObjects
    FOR XML PATH('row'),ROOT('root')
);
SELECT @myXML2;

现在,当您设法将FOR XML的结果分配给变量时,您必须学习如何从动态创建的SQL中返回它:

DECLARE @cmd NVARCHAR(MAX)=
'SELECT TOP 1 @TheOutput=name FROM sys.objects;'; --@TheOutput "inside" is not declared yet!

DECLARE @IReadIt NVARCHAR(100); --define a variable "outside"

--Now we use sp_executesql to declare the inner variable and to bind the outer to the inner variable
EXEC sp_executesql @cmd,N'@TheOutput NVARCHAR(100) OUTPUT',@TheOutput=@IReadIt OUTPUT;

SELECT @IReadIt;