2013-03-26 12 views
34

Sto cercando di creare un elenco di valori separati da virgola da una tabella di SQL Server 2005, proprio come in JanetOhara's question. Sto usando una query simile a quella presentata in techdo's answer alla domanda.Come evitare la codifica dei caratteri quando si utilizza "FOR XML PATH"?

Tutto funziona, tranne che l'elenco di valori sta ottenendo la codifica XML. Quale dovrebbe essere:

Sports & Recreation,x >= y 

è invece che ritorna come:

Sports & Recreation,x <= y 

C'è un modo per disattivare la codifica dei caratteri XML quando si utilizza "FOR XML" in SQL Server?

risposta

81

Hai solo bisogno di utilizzare le opzioni giuste con FOR XML. Ecco un approccio che evita la codifica:

USE tempdb; 
GO 

CREATE TABLE dbo.x(y nvarchar(255)); 

INSERT dbo.x SELECT 'Sports & Recreation' 
    UNION ALL SELECT 'x >= y' 
    UNION ALL SELECT 'blat' 
    UNION ALL SELECT '<hooah>'; 

-- bad: 
SELECT STUFF((SELECT N',' + y 
FROM dbo.x FOR XML PATH(N'')), 1, 1, N''); 

-- good: 
SELECT STUFF((SELECT N',' + y 
FROM dbo.x FOR XML PATH, TYPE).value(N'.[1]', 
N'nvarchar(max)'), 1, 1, N''); 

GO 
DROP TABLE dbo.x; 
+6

L'aggiunta di 'type' e' .value ('. [1]', nvarchar (max) ') 'ha funzionato perfettamente. Grazie per l'aiuto. – dangowans

+4

TYPE dice a SQL di restituire l'XML effettivo, quindi devi "interrogare" questo XML per il valore che desideri sia ".value ('. [1]', nvarchar (max) '). Ulteriori informazioni qui: http://technet.microsoft.com/en-us/library/ms190025.aspx – ProVega

+1

Il primo carattere nella mia stringa era un '<', questo è stato per qualche motivo omesso dopo l'implementazione di questa soluzione. Ho risolto il problema aggiungendo un spazio vuoto all'inizio della stringa: – alan

0

vedere questo post su Creating concatenated delimited string from a SQL result set and avoid character encoding when using “FOR XML PATH”

Un approccio alternativo potrebbe essere quello di fare affidamento sulla concatenazione di caratteri (ovviamente SQL non è grande con le operazioni di stringa come si è sviluppato per il lavoro con teoria degli insiemi)

USE tempdb; 
GO 

CREATE TABLE dbo.x (y NVARCHAR(255)); 
INSERT dbo.x 
SELECT 'Sports & Recreation' 
UNION ALL 
SELECT 'x >= y' 
UNION ALL 
SELECT 'blat' 
UNION ALL 
SELECT '<hooah>'; 

DECLARE @delimitedText varchar(max) 
SET @delimitedText='' 
SELECT @delimitedText += CASE WHEN LEN(@delimitedText) > 0 THEN +','+ y ELSE y END 
FROM dbo.x 

SELECT @delimitedText 
GO 
DROP TABLE dbo.x; 
GO