Если ваш xml вывод относительно небольшой (<4000 символов), то вы можете использовать этот SP: </p>
IF EXISTS (SELECT TOP 1 1 FROM sys.objects WHERE object_id = OBJECT_ID('dbo.USP_WRITE_UNICODE_STRING_TO_FILE') AND type = 'P')
BEGIN
DROP PROCEDURE dbo.USP_WRITE_UNICODE_STRING_TO_FILE
END
GO
-- =============================================
-- Description: Writes the specified Unicode string to the specified file.
-- Permissions: This stored procedure uses xp_cmdshell which is disabled by default. To enable it:
-- 1. In Management Studio connect to a component of SQL Server.
-- 2. In Object Explorer, right-click the server, and then click Facets.
-- 3. In the View Facets dialog box, expand the Facet list, and select the Surface Area Configuration.
-- 4. In the Facet properties area, select XPCmdShellEnabled property and set its value to True.
-- 5. Click OK.
-- Example: EXEC dbo.USP_WRITE_UNICODE_STRING_TO_FILE'<root> <a b="c" /> </root>', 'C:\Test.xml', 1;
-- =============================================
CREATE PROCEDURE dbo.USP_WRITE_UNICODE_STRING_TO_FILE
(
@Str NVARCHAR(4000),
@XmlFilePath NVARCHAR(256),
@Debug BIT = 0
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Str1 NVARCHAR(MAX),
@Cmd NVARCHAR(4000),
@MaxLen int = 4000;
--see: http://technet.microsoft.com/en-us/library/bb490897.aspx
SET @Str1 = REPLACE(REPLACE(REPLACE(@Str, '>', '^>'), '<', '^<'), '"', '^"');
-- '>' Writes the command output to a file
SET @Str1 =N'ECHO ' + @Str1 + N'>"'+ @XmlFilePath + N'"';
IF @Debug = 1
BEGIN
DECLARE @Msg varchar(128) = 'The total lenght is ' + CAST(LEN(@Str1) AS VARCHAR(10)) + ' characters.'
PRINT @Msg;
PRINT @Str1;
END
IF (LEN(@Str1) > @MaxLen)
RAISERROR ('The input string is too long', 11, 0);
ELSE
SET @Cmd = CAST (@Str1 AS NVARCHAR(4000));
EXEC master..xp_cmdshell @Cmd, NO_OUTPUT;
END
GO
--Test 1
DECLARE @Str NVARCHAR(4000);
DECLARE @Xml xml = '<root> <a b="c" /> </root>';
SET @Str = CAST (@Xml AS NVARCHAR(4000));
EXEC dbo.USP_WRITE_UNICODE_STRING_TO_FILE @Str, 'C:\Test.xml', 1;
GO
--Test 2
DECLARE @Str NVARCHAR(4000);
SET @Str = REPLICATE('a', 4000);
EXEC dbo.USP_WRITE_UNICODE_STRING_TO_FILE @Str, 'C:\Test.xml', 1;
GO
Если вы не работаете с Unicode, вы можете создать еще один SP: USP_WRITE_NON_UNICODE_STRING_TO_FILE, который будет очень похож на предыдущий со следующими изменениями:
CREATE PROCEDURE dbo.USP_WRITE_NON_UNICODE_STRING_TO_FILE
(
@Str VARCHAR(8000),
@XmlFilePath NVARCHAR(256),
@Debug BIT = 0
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Str1 VARCHAR(MAX),
@Cmd VARCHAR(8000),
@MaxLen int = 8000;
...
SET @Cmd = CAST (@Str1 AS VARCHAR(8000));
Этот SP позволяет использовать в два раза длиннее строку ввода (<8000 символов). </p>
Если ваш XML длиннее 8000, но меньше 1 МБ, вы можете использовать утилиту sqlcmd без команды: XML ON. Это значительно упрощает использование утилиты, поскольку вам не нужен отдельный файл input_file с включенной командой XML ON. Вот пример:
DECLARE @Cmd NVARCHAR(4000);
SET @Cmd = N'sqlcmd -S ' + @@SERVERNAME + N' -d ' + DB_NAME() +
N' -Q "SET NOCOUNT ON; DECLARE @Xml xml = ''<root> <a >b</a> </root>''; SELECT CONVERT(NVARCHAR(MAX), @Xml);" -o "C:\Test.xml" -y 0';
PRINT @Cmd;
EXEC master..xp_cmdshell @Cmd, NO_OUTPUT;
Вы также можете использовать SP здесь:
CREATE PROCEDURE dbo.USP_SAMPLE_PROCEDURE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Xml xml;
SET @Xml = (SELECT name, type_desc FROM sys.objects FOR XML PATH('object'), ROOT('sys.objects'));
SELECT CONVERT(NVARCHAR(MAX), @Xml)
END
GO
DECLARE @Cmd NVARCHAR(4000);
SET @Cmd = N'sqlcmd -S ' + @@SERVERNAME + N' -d ' + DB_NAME() +
N' -Q "EXEC dbo.USP_SAMPLE_PROCEDURE;" -o "C:\Test.xml" -y 0';
PRINT @Cmd;
EXEC master..xp_cmdshell @Cmd, NO_OUTPUT;
GO
Если ваш XML превышает 1 МБ, вы должны использовать: XML ON команду в отдельном скрипте и указать ее в качестве параметра -i input_file.