2017-08-23 1 views
0

J'essaie de créer XMLTYPE à partir de la colonne CLOB et de spécifier explicitement le jeu de caractères. J'ai trouvé qu'il y a une fonction XMLTYPE.createXML surchargée qui accepte le jeu de caractères mais quand j'exécute en passant des arguments supplémentaires, j'obtiens une erreur. Pourquoi?Création d'Oracle XMLTYPE à partir de CLOB en spécifiant le jeu de caractères

SELECT 
XMLTYPE.createXML(TO_CLOB ('<node1><node2>the &#180; character</node2></node1>'),NLS_CHARSET_ID('AL32UTF8'),'',1,1) 
from dual; 

erreur:

ORA-06553: PLS-306: wrong number or types of arguments in call to 'CREATEXML'

La raison pour laquelle je donner la peine passer le jeu de caractères est, colonne de CLOB contient des caractères qui sont codés avec caractères différent que le jeu de caractères de base de données (qui par exemple ne support # 180).

+0

Je regarde la documentation ici: https://docs.oracle.com/database/121/ARPLS/t_xml.htm#ARPLS71959 et Je ne vois pas l'option que vous mentionnez. Où avez-vous trouvé cette surcharge? Êtes-vous sûr que c'était pour Oracle (et pas, par exemple, pour Java ou qui sait quoi d'autre)? – mathguy

+0

Votre CLOB est ASCII simple - pourquoi devez-vous spécifier un jeu de caractères? –

+0

Recherchez l'argument csid IN number, voir docs.oracle.com/database/121/ARPLS/t_xml.htm#ARPLS71959. ... n'est qu'un exemple. createXML sera exécuté avec une colonne qui contient des caractères spéciaux qui ne peuvent pas être décodés avec le jeu de caractères de base de données NLS_CHARACTERSET. – DevDav

Répondre

1

The reason why I bother passing the character set is, CLOB column contains characters which are encoded with different character set than the database character set (which for example doesn't support #180).

Ce que je ne comprends pas. #180; est simple ASCII simple, il devrait fonctionner pour n'importe quelle condition.

Il suffit de lancer

SELECT 
    XMLTYPE.createXML(TO_CLOB('<node1><node2>the &#180; character</node2></node1>')) 
from dual; 

ou encore plus court

SELECT 
    XMLTYPE('<node1><node2>the &#180; character</node2></node1>') 
from dual; 

Maintenant, supposons que votre XML contient des caractères qui ne sont pas pris en charge par le jeu de caractères de base de données, dans ce cas, votre XML pourrait être <node1><node2>the ´ character</node2></node1> par exemple .

Tout d'abord, vous ne pouvez pas stocker (ou utiliser) un caractère CLOB (ou VARCHAR2) qui ne sont pas pris en charge par le caractère de base de données ensemble - jamais! Vous devez utiliser NCLOB (ou NVARCHAR2) qui sont basés sur Jeu de caractères de la base de données nationale et prennent généralement en charge tout caractère Unicode.

Vous pouvez spécifier le jeu de caractères dans XMLTYPE.createXML(), mais vous devez fournir XML en tant que BLOB. Vous pouvez le faire comme ceci:

DECLARE 
    xmlString NCLOB := '<node1><node2>the '||NCHR(180)||' character</node2></node1>'; 
    xmlDoc XMLTYPE;  
    xmlBinary BLOB; 

    lang_context INTEGER := DBMS_LOB.DEFAULT_LANG_CTX; 
    dest_offset INTEGER := 1; 
    src_offset INTEGER := 1; 
    read_offset INTEGER := 1; 
    warning INTEGER; 

BEGIN 

    DBMS_LOB.CREATETEMPORARY(xmlBinary, TRUE); 
    DBMS_LOB.CONVERTTOBLOB(xmlBinary, xmlString, DBMS_LOB.LOBMAXSIZE, dest_offset, src_offset, 2000, lang_context, warning); 
    xmlDoc := XMLTYPE.createXML(xmlBinary, 2000, NULL, 1, 1); 
END; 

2000 est le csid du jeu de caractères de votre base de données nationale. Utilisez

SELECT PARAMETER, VALUE, NLS_CHARSET_ID(VALUE) 
FROM NLS_DATABASE_PARAMETERS 
WHERE PARAMETER LIKE '%CHARACTERSET'; 

pour obtenir vos identifiants.

Quelques notes:

J'ai essayé avec la chaîne N'<node1><node2>the ´ character</node2></node1>', mais Oracle remplacé ´ immédiatement ¿. Je n'ai pas réussi à entrer ´ directement.

Presque toutes les valeurs XML Functions de retour VARCAHR2 (non NVARCAHR2), aussi la plupart des fonctions XMLTYPE membres travaillent avec CLOB (non NCLOB). Si vous venez de lire et de stocker vos documents XML en tant que XMLTYPE dans votre base de données, cela devrait aller, cependant dès que vous démarrez des opérations avec ces données tôt ou tard, vous rencontrerez une erreur de conversion.Vous devriez vraiment envisager de migrer votre jeu de caractères de base de données, voir Character Set Migration et/ou Oracle Database Migration Assistant for Unicode

0

Vous pouvez utiliser directement la fonction XMLType

SELECT XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>' 
    ||TO_CLOB ('<node1><node2>the &#180; character</node2></node1>')) myxml 
FROM dual;