I have a query that generates XML files and loads them to FTP with .
I need to switch encoding to UTF-8 as follows:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[MyXMLTest]
@FileDestinationDir VARCHAR(2000)
-- to call procedure specify your own file path
-- EXEC [Audit_DBA].[dbo].[MyXMLTest] 'E:\NLP\GovwinIQ_Ontology\NewFolder'
AS
SET QUOTED_IDENTIFIER ON
IF OBJECT_ID (N'InputTemp.dbo.XMLTest', N'U') IS NOT NULL
DROP TABLE InputTemp.dbo.XMLTest;
CREATE TABLE InputTemp.dbo.XMLTest
(
[Id] INT NOT NULL,
[FirstName] VARCHAR(100) NOT NULL,
[LastName] VARCHAR(100) NOT NULL,
[Address] VARCHAR(100) NOT NULL
);
INSERT INTO InputTemp.dbo.XMLTest ([Id], [FirstName], [LastName], [Address])
VALUES (12, 'Zhuk', 'Termik', '123 Gam Str, Boston, NY');
--SELECT * FROM InputTemp.dbo.XMLTest
DECLARE @FilePath VARCHAR(4000)
DECLARE @SQLStr NVARCHAR(4000),
@Cmd NVARCHAR(4000),
@Ret INT
DECLARE @Id INT;
SELECT @Id = 12;
SELECT @SQLStr =
'SELECT N''<?xml version=''''1.0'''' encoding=''''UTF-8''''?>'' + (SELECT CAST((SELECT [Id], [FirstName], [LastName], [Address] FROM InputTemp.dbo.XMLTest AS Body WHERE Id = ''' + str(@Id) + ''' FOR XML AUTO, ELEMENTS) AS NVARCHAR(MAX)))'
SELECT @SQLStr AS SQLStr
SELECT @FilePath = @FileDestinationDir+'\NewFolder'+ltrim(rtrim(str(@Id)))+'.xml'
SELECT @Cmd = ' bcp " ' + @SQLStr + '" queryout '+@FilePath+' -c -C65001 -r "" -T -S ' +@@ServerName
EXEC @Ret = master.dbo.xp_cmdshell @Cmd
IF OBJECT_ID (N'InputTemp.dbo.XMLTest', N'U') IS NOT NULL
DROP TABLE InputTemp.dbo.XMLTest;
GO
There are some things to know:
<?xml blah ?>
) to a native SQL-Server XML typed variable or column. This will either fail ("...switch the encoding") or the xml-declaration will disappear.NVARCHAR(MAX)
. But you cannot re-cast (re-convert) this to an XML without failing or losing the declaration.UCS-2
(very close to UTF-16
) in any case.VARCHAR
(CHAR
) type is not utf-8
but extended ASCII (depending on a COLLATION
)encoding="x"
and store the file with an encoding of y - but you shouldn't.utf-8
declaration to XML when it is VARCHAR
and it will cast a string with utf-16
when it is NVARCHAR
, but you cannot cross this (Read this related answer). Other encodings very likely lead to cannot switch the encoding error.About your code
@SQLStr
and @cmd
to NVARCHAR(MAX)
, othewise you might get in troubles with non-plain-latin characters.CURSOR
, you should fill an XML-typed variable with the result of your statement, cast this to NVARCHAR(MAX)
and add the declaration to this string. Do not cast the result back to XML.BCP
docs. Stating -w
will write unicode
(wide), which is not utf-8
(what you write into the declaration has no effect here).Read this related answer, showing utf-8 export with BCP on SQL-Server 2016