7
votes

Erreur Oracle SQL Developer "String Literie Trop longue" "

J'ai le SQL suivant que je souhaite exécuter dans Oracle SQL Developer contre un serveur Oracle 10G:

Error at Command Line:1 Column:0 Error report: SQL Error: ORA-01704: string literal too long
01704. 00000 -  "string literal too long"
*Cause:    The string literal is longer than 4000 characters.
*Action:   Use a string literal of at most 4000 characters.
           Longer values may only be entered using bind variables.


0 commentaires

5 Réponses :


12
votes

Vous ne pouvez pas contourner cela avec "plain" SQL. (Mais je serais heureux d'être avéré faux)

Vous aurez besoin d'une sorte de langage de programmation (par exemple Java, de procédure stockée) pour y faire face.

Une alternative consiste à télécharger les données XML dans une table (peut être effectuée avec SQL * Loader) et utiliser les valeurs de colonne dans votre requête.

C'est l'une des limitations de Oracle qui me rend vraiment des noix. Il y a 20 ans, cela aurait pu être quelque peu acceptable, mais de nos jours ...


1 commentaires

J'espère que vous vous trompez aussi bien mais j'attends que vous soyez correct.



1
votes

Une solution de contournement possible consiste à utiliser des blocs PL / SQL:

DECLARE
      xml VARCHAR2(32000) := 
     '<theRange>
        <theRow><First>Bob</First><Last>Smith</Last><Age>30</Age></theRow>
        <theRow><First>Sue</First><Last>Jones</Last><Age>34</Age></theRow>
    ...
    ...
    ...
        <theRow><First>Tom</First><Last>Anderson</Last><Age>39</Age></theRow>
        <theRow><First>Ali</First><Last>Grady</Last><Age>45</Age></theRow>
      </theRange>';
BEGIN
  INSERT INTO temp_table(last,first,age)
  SELECT last, first, age FROM (
    SELECT extractvalue(column_value, '/theRow/First') FIRST,
           extractvalue(column_value, '/theRow/Last') LAST,
           to_number(extractvalue(column_value, '/theRow/Age')) Age
      FROM TABLE(XMLSequence(XMLTYPE(xml).extract('/theRange/theRow'))))
  )
   WHERE age BETWEEN 30 AND 35;
END;


3 commentaires

Toute façon d'insérer les résultats dans une table temporaire que je peux choisir parmi?


Une autre question. Est de 32 000 la limite à ce genre de chose? Si j'ai dépassé ce montant, aurais-je besoin de le calculer en 32 000 blocs de caractères.


32K (32767) IS, IIRC, la limite de taille absolue en octets pour une variable Varchar2 dans PL / SQL. Donc, vous auriez besoin d'utiliser des morceaux.



2
votes

Où est-ce grand gros morceau de XML? Je suppose que vous ne le tapez pas.

En règle générale, je regarderais un programme qui lit la source et la transforme en un clob. Cela pourrait être un Perl / Python / Quel que soit le script sur un client, ou une routine latérale du serveur qui tire la valeur d'un serveur Web.


1 commentaires

Le XML vient de quelques endroits différents. Actuellement, je construis un script SQL qui contient le XML, puis l'exécutant dans SQL Server. Je veux modifier les choses à courir à Oracle mais je rencontre des problèmes.



7
votes

Vous aurez besoin d'utiliser un clou comme entrée sur xmltype () au lieu d'un varchar.

à l'aide de dbms_lob.loadclobfomfile pour charger le XML à partir d'un fichier ou en rupture de la XML en 32000 morceaux de caractères et ajoutant au clob. xxx


1 commentaires

Comment construisez-vous le "CLOB"? Fournir une solution complète qui fonctionne.



2
votes

Vous pouvez utiliser SQL Solution de contournement à l'aide d'insertions / mises à jour où chaque partie si moins de 4000 caractères.

1 Faites l'insert comme insert avec une première partie est le littéral SQL jusqu'à 4000 caractères. 2 Faites les pièces supplémentaires comme mise à jour concaténant les pièces précédentes avec la partie suivante où la partie suivante est de 4000 caractères. 3 Répétez l'étape 2 jusqu'à ce que tout le grand littéral SQL soit mis à jour.

exemple, xxx


1 commentaires

Vous pouvez également faire insert ... valeurs (to_clob ('') || to_clob ('') || to_clob (...)) ; Mais si vous avez vraiment beaucoup de parties, cela deviendra lent à moins que vous n'utilisez des parenthèses pour vous assurer que les mêmes morceaux de longueur sont concaténés (comme ((((((c || b) || (((((((((( E || f) || (g || h))) ), tellement mieux ne pas utiliser ce hack sale :)