【问题标题】:Creating XML, exporting using bulk copy创建 XML,使用批量复制导出
【发布时间】:2018-02-20 11:49:42
【问题描述】:

我认为在 FOR XML 和 CTE 旁边使用 bcp 有一些“独特”之处。 (也许不是?)

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

我应该在命名空间和 CTE 周围“包装” bcp 吗?我应该单独创建它然后连接吗? 我尝试了所有方法,但似乎没有任何效果。


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

 ... 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' 

编辑:

我试着这样写: ...

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

我希望我的问题不会显得含糊不清,如果是这样,请要求澄清。

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

【问题讨论】:

  • 我的回答对你有帮助吗?

标签: sql-server bcp sqlxml


【解决方案1】:

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

我觉得我的魔法水晶球是对的。它告诉我,您需要帮助如何将FOR XML 的结果分配给变量,以及如何从动态创建的代码中返回变量值。看看这个:

如果语句的结果是标量,可以直接在SELECT内赋值;

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

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

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;

【讨论】:

    猜你喜欢
    • 2018-06-30
    • 2018-07-15
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多