Oracle BLOB en base64 CLOB
Puis-je convertir un oracle BLOB en Base64 CLOB dans Un go?
comme:
CREATE TABLE test
(
image BLOB,
imageBase64 CLOB
);
INSERT INTO test(image)
VALUES (LOAD_FILE('/full/path/to/new/image.jpg'));
UPDATE test SET imageBase64 = UTL_ENCODE.base64_encode(image);
commit;
Je sais que je peux ajouter des fonctions/procédures Stockées pour faire le travail. Les performances aspect est très important,donc je demande si il existe un moyen de surmonter les 32K limitation en poussant directement les données dans un CLOB.
- Êtes-vous prêt à le faire par l'intermédiaire d'une procédure stockée, c'est à dire sans une mise à jour+fonction?
- Je veux éviter une procédure stockée qui va traiter les données en concaténant CLOBS.
Vous devez vous connecter pour publier un commentaire.
À condition que stockées procs serait en dépit d'être une alternative viable pour vous, voici une solution possible à votre problème ...
Tout d'abord, faisons en sorte que cette belle
base64encode()
fonction de Tim Hall dans une procédure ...Le "truc" ici est d'utiliser directement la persistance de la LOB locators dans les appels à des procédures/fonctions. Pourquoi "persistante"? Parce que si vous créez une fonction qui retourne un LOB, puis il y a un temporaire LOB créé dans le fond et cela signifie quelque TEMP disque/mémoire d'utilisation et LOB contenu de reproduction. Pour les grandes LOBs cela peut entraîner un gain de performance. Afin de satisfaire votre exigence de ce qui en fait le plus performant possible, vous devriez éviter ce TEMP d'utilisation de l'espace. Donc, pour cette approche, une procédure stockée à la place d'une fonction doit être utilisée.
Puis, bien sûr, la procédure doit être nourri avec la persistance d'un LOB locators. Que vous avez à faire qui, à nouveau, avec une procédure stockée, où, par exemple, vous insérez un vide LOB (dans les faits, la création d'un nouveau MÉTIER locator) à une table d'abord, et puis à fournir nouvellement créé LOB locator pour l'encodage base64 routine ...
Remarque: bien sûr, si vous en base64 encode seulement des petits fichiers, la taille réelle dépend de votre PGA paramètres, je deviner; une question pour un DBA, ce l'est), alors la fonction peut être tout aussi performantes que cette procédure basée sur un. Base64-encodage d'un fichier de 200 mo sur mon ordinateur portable a eu 55 secondes avec la fonction+approche de mise à jour, de 14 secondes à la procédure d'approche. Pas exactement un démon de la vitesse, afin de choisir ce qui convient à vos besoins.
Remarque: je crois que cette procédure basée sur l'approche peut être accéléré par la lecture du fichier d'inmemory morceaux en boucle, en base64 codant pour les morceaux à l'autre inmemory morceaux et en les ajoutant à la fois à la cible persistante LOBs. De cette façon, vous devriez faire de la charge de travail encore plus facile en évitant les re-lecture de la pleine
test.image
LOB contenu par lebase64encode()
procédure.Cette fonction a obtenu à partir d'ici devrait faire le travail.
Puis la mise à jour peut ressembler à
Remarque que peut-être la fonction doit être optimisée grâce à la fonction DBMS_LOB.AJOUTER à la place de l'opérateur de concaténation. Essayez, si vous avez des problèmes de performances.
J'ai résolu ce même problème au travail, à l'aide d'un Java procédure stockée. Il n'y a pas de segmentation/contatenation de VARCHAR2s impliqués dans une telle approche, car la capacité de codage/décodage en base64 est nativement intégré à Java, il suffit d'écrire un Oracle de la fonction de cette mince enveloppe la méthode Java qui fonctionne bien et est de haute performance, car dès que vous avez exécuté une fois, de la JVM HotSpot compile le Java proc en au code de bas niveau (de haute performance comme un C fonction stockée). Je vais modifier cette réponse plus tard et ajouter les détails au sujet de ce code Java.
Mais pour reculer d'un pas question, pourquoi êtes-vous le stockage de ces données à la fois comme un BLOB et encodées en base64 (CLOB)? Est-ce parce que vous avez des clients qui veulent utiliser les données dans le dernier format? J'aimerais vraiment préfèrent ne stocker le BLOB format. Une raison en est que la version encodée en base 64 peut être le double de la taille de l'original BLOB binaire, afin de les stocker à la fois les moyens éventuellement 3x le stockage.
Une solution, celle que j'ai mis en œuvre au travail, pour créer votre propre Java fonction stockée
base64_encode()
qui code binaire --> base64, puis utiliser cette fonction pour encoder en base64 à la volée au moment de la requête (c'est pas cher). À partir de l'application/côté client, vous de requête serait quelque chose commeSELECT base64_encode(image) FROM test WHERE ...
Si le code de l'application ne peut pas être touché (c'est à dire des LITS d'application) ou, si les développeurs ne sont pas très heureux à ce sujet à l'aide d'une fonction, vous pourriez abstrait pour eux (puisque vous utilisez 11g+) en utilisant un VIRTUEL (calculée) de la colonne sur la table qui contient le résultat de
base64_encode(image)
. Il fonctionnerait comme une vue, en ce qu'il ne serait pas physiquement magasin de la codées CLOBs, mais permettrait de générer eux au moment de la requête. Pour tout client, ils ne seraient pas en mesure de dire qu'ils ne sont pas de la lecture d'une colonne physique. L'autre avantage est que si vous mettez à jour le jpg (BLOB), le virtuel CLOB est immédiatement et automatiquement mis à jour. Si vous devez insérer/mettre à jour/supprimer un énorme lot de Gouttes, vous serais d'économiser 66% de la refaire/archivelog volume pour ne pas avoir à traiter toutes les CLOBs.Enfin, pour les performances, assurez-vous que vous utilisez SecureFile Lob (à la fois pour les BLOBs et CLOBs). Ils sont vraiment beaucoup plus vite et mieux, dans tous les sens.
Mise à JOUR - j'ai trouvé mon code, au moins la version qui utilise Java Procédure Stockée pour faire l'inverse (la conversion d'un encodées en base64 CLOB à son BLOB binaire de la version). Il ne serait pas facile d'écrire l'inverse.
La façon la plus simple que j'ai trouvé, qui fonctionne avec des caractères spéciaux (dans votre cas, vous n'avez pas ce problème), est à l'aide de dbms_lob.converttoclob.
Créer encapsulé Procédure:
Ensuite, vous pouvez utiliser: