Создание XML, экспорт с использованием массового копирования
Я предполагаю, что есть что-то "уникальное" с использованием bcp наряду с FOR XML и CTE. (Возможно, нет?)
Как я могу экспортировать XML, которые я создал динамически? Как использовать bcp, если мой запрос реализует CTE, если я использую WITH NAMESPACES?
Должен ли я "обернуть" bcp вокруг пространств имен и CTE? Должен ли я создать его отдельно, а затем объединить? Я пытался все это, но ничего не работает.
Моя попытка (Конечно, выбор 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 не будет указывать на какие-либо синтаксические ошибки.
1 ответ
Я предпочел бы вставить эти XML-файлы в промежуточную таблицу и сделать BCP
оттуда. Но ваша проблема тоже может быть решена...
Я думаю, что мой магический хрустальный шар прав. Он показал мне, что вам нужна помощь, как помочь FOR XML
результат для переменной и как вернуть значение переменной из динамически созданного кода. Посмотри на это:
Если результат оператора скалярный, вы можете назначить его в SELECT
непосредственно;
DECLARE @SomeName VARCHAR(MAX);
SELECT TOP 1 @SomeName=name FROM sys.objects;
SELECT @SomeName;
И вы можете назначить FOR XML
результат (то же самое с простым скалярным значением), просто оборачивая 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;