Nous utilisons Nous avons également une couche pour composer automatiquement des requêtes, du code pseudo-SQL écrit dans .NET (quelque chose comme Sqlalchemy pour Python). P>
Notre couche envoie actuellement n'importe quelle chaîne en guillemets simples Maintenant, nous avons créé une méthode pour faire plusieurs inserts avec la construction suivante: Cet algorithme pourrait composer des requêtes dans lesquelles le même champ de chaîne est parfois transmis comme La condition décrite provoque un Une solution consiste à utiliser le Une autre solution consiste à instruire notre couche de mettre Remarque: tous nos champs sur dB sont soit oracle ref: http://docs.oracle.com/cd/b19306_01/ Server.102 / B14225 / CH7PROGRUNICODE.HTM P> oracle 10g code> et
oracle 11g code>. p>
' code> et, si contient des caractères non ANSI, il compose automatiquement le
désistry code> avec des caractères spéciaux écrits comme unicode octets (comme
\ 00e0 code>). p>
insérer dans ... (...)
Sélectionnez ... de Dual
Union Tous Sélectionnez ... de Dual
... code> p>
'ma simple chaîne' code> et parfois enveloppé comme
unistr (ma chaîne avec des caractères spéciaux comme 00E0 ') < / code>. p>
ORA-12704: MisMatch Set de caractères Code>. P>
Insérer tout code> construction mais il est très lent em> fort> comparé à celui utilisé maintenant. p>
n code> devant n'importe quelle chaîne (à l'exception de ceux déjà enveloppés avec
Unistr code>). C'est simple. P>
NCHAR code> ou
NVARCHAR2 code>. P>
3 Réponses :
fondamentalement ce que vous demandez est, existe-t-il une différence entre la manière dont une chaîne est stockée avec ou sans la fonction N.
Vous pouvez simplement vérifier vous-même en considérant: P>
SQL> create table test (val nvarchar2(20)); Table TEST created. SQL> insert into test select n'test' from dual; 1 row inserted. SQL> insert into test select 'test' from dual; 1 row inserted. SQL> select dump(val) from test; DUMP(VAL) -------------------------------------------------------------------------------- Typ=1 Len=8: 0,116,0,101,0,115,0,116 Typ=1 Len=8: 0,116,0,101,0,115,0,116
Pourrait-il y avoir une décrément de performance appliquant n partout sur les littéraux string?
"Peut-il y avoir une décrément de performance appliquant n partout sur les littéraux strings?" Non, ce n'est pas parce que toute valeur de caractère insérée dans la colonne NCHAR convertie en NCHAR implicitement ou explicitement.
@Mikhailovvalentine merci. Alors, avec n code>, je suis juste explicit-ing i> un processus qui se produit implicitement de toute façon?
Je suppose que vous obtenez une erreur Lorsque vous utilisez une fonction "Unistr prend comme argument un texte littéral ou une expression qui
résout à des données de caractère et le renvoie dans le caractère national
ensemble. " p>
blockQuote> Lorsque vous convertissez des valeurs explicitement à l'aide de Donc, si vous avez un insert tel que: P> Vos données dans le premier champ d'insertion seront: et d'ailleurs, pourquoi ne pas simplement insérer toutes les valeurs comme "ORA-12704: MISMATCH" CODE> Parce que vos données à l'intérieur de citations considérées comme Char mais vos champs sont NCHAR, il est donc rassemblé à l'aide de différents caractères, l'utilisant < Code> nls_characterset code>, l'autre
nls_nchar_charactterset code>.
unistr code>, il convertit les données de
char code> à < Code> nchar code> (dans tout cas qui convertit également les valeurs codées en caractères) comme l'oracle docs dis: p>
N code> ou
to_nchar code> Vous obtenez uniquement des valeurs dans
nls_nchard_characterset code> sans décodage. Si vous avez des valeurs codées comme ceci
"\ 00e0" code> ils ne seront pas décodés et seront considérés comme inchangés. P>
'ma chaîne avec des caractères spéciaux tels que \ 00E0' code> pas
'ma chaîne avec des caractères spéciaux comme à ã ' code>. C'est le seul effet secondaire que je suis au courant. D'autres requêtes doivent déjà utiliser l'encodage NLS_NCHAR_CHARACTERSET, de sorte que cela ne devrait donc pas être un problème à l'aide d'une conversion explicite. P>
N'MY String avec des caractères spéciaux comme ã ' code>? Il suffit de les coder dans UTF-16 (je suppose que vous utilisez UTF-16 pour NCHARS) si vous utilisez un codage différent dans le logiciel 'Upper Niveau'. P> P>
"Je suppose que vous obtenez une erreur" ORA-12704: MisMatch "Parce que vos données à l'intérieur des citations considérées comme Char mais vos champs sont NCHAR" i> non, je reçois l'erreur parce que je mélange pas -unicode et texte unicode avec Union tout code>.
"Mais si vous avez des valeurs codées comme ceci" \ 00e0 ", ils ne seront pas décodés et seront considérés comme" " i> Les chaînes contenant des caractères spéciaux sont automatiquement enveloppées avec Unistr code> Par notre couche, d'autres ne le sont pas. C'est pourquoi le mélange des annonces, et c'est pourquoi j'ai besoin de N pour d'autres cordes.
"Et au fait, pourquoi ne pas simplement insérer toutes les valeurs comme N'MY String avec des caractères spéciaux tels que à ' code>" i> Vous dites donc qu'il n'y a pas de différence entre utilisation
Unistr ('\ 00e0') code> et
N'à ' code>?
"Aucune différence entre UTILISER UNISR ('\ 00E0') et N'à '" au moins lorsque j'insère à l'aide de JDBC ou de développeur SQL, je ne peux pas trouver une différence.
"Non, je reçois l'erreur parce que je mélange un texte non unicode et unicode avec l'union tout." Essayez de créer une table d'essai avec des colonnes Char et NCHAR et essayez de faire une insertion à l'aide de N'String 'pour N caractère et «chaîne» pour Char - cela fonctionnera.
Oui en effet, parce qu'ils sont deux colonnes distinctes. Dans mon cas, lors de l'utilisation de Union tout code>, les valeurs de chaque sous-
Sélectionnez l'instruction CODE> Fusionner dans une seule colonne avant d'être insérée, elles doivent donc avoir le même ensemble de caractères.
Si vous avez des chances de modifier la brandon de la base de données, cela faciliterait votre vie. Je travaillais sur d'énormes systèmes de production et j'ai trouvé la tendance que, à cause de l'espace de stockage, tout le monde passe à Al32utF8 et que les soucis de l'internationalisation deviennent lentement les souvenirs douloureux du passé. P>
J'ai trouvé que la chose la plus facile est d'utiliser AL32UTF8 en tant que Chart de l'instance de base de données, et utilisez simplement Varchar2 partout. Nous lisons et écrivons des chaînes Standard Java Unicode via JDBC en tant que variables liées sans préjudice, ni violon. P>
Votre idée de construire un énorme texte d'inserts SQL peut ne pas bien augmenter pour plusieurs raisons: P>
Qu'est-ce que vous essayez d'atteindre est un insert de masse. Utilisez le mode de lot JDBC du pilote Oracle pour effectuer cela à la vitesse de la lumière, voir par exemple: http://viralpatel.net/blogs/batch-insert-in-java-jdbc/ p>
Notez que la vitesse d'insertion est également affectée par des déclencheurs (qui doivent être exécutés) et des contraintes de clé étrangères (qui doivent être validées). Donc, si vous êtes sur le point d'insérer plus de quelques milliers de lignes, envisagez de désactiver les déclencheurs et des contraintes de clé étrangère et leur permettez-leur après l'insertion. (Vous perdrez les appels de déclenchement, mais la validation de contrainte après l'insertion peut avoir un impact.) P>
Considérez également la taille du segment de restauration. Si vous insérez un million d'enregistrements, cela nécessitera un énorme segment de restauration, qui entraînera probablement un échange grave sur le support de stockage. C'est une bonne règle de commettre à s'engager après chaque 1000 enregistrements. p>
(Oracle utilise la versioning au lieu de verrous partagés, une table avec des modifications non engagées est toujours disponible pour la lecture. Le taux de validation de 1000 enregistrements signifie environ 1 commit par seconde - assez lent pour le bénéfice des tampons d'écriture, mais suffisamment rapide pour ne pas interférer avec d'autres humains disposés à mettre à jour la même table.) p>
"Il existe une longueur fixe de l'instruction SQL maximale autorisée - elle ne fonctionnera donc pas avec 10000 inserts" i>, tout simplement pas vrai. Oracle n'a pas de limite de longueur fixe B>, voir Stackoverflow.com/Questtions/14355819/... . BTW, notre couche scindre automatiquement la requête en taille prédéfinie. Nous n'avons donc pas besoin de vous inquiéter de telles choses.
"Ce que vous essayez d'atteindre est un insert de masse. Utilisez le mode de lot JDBC du pilote Oracle" i> Je sais qu'il existe des moyens d'insertion en vrac, c'est-à-dire à partir d'un fichier texte formaté, mais ceci est tout simplement pas le cas. Notre couche compose également des requêtes pour SQLServer et Postgres. BTW, personne n'a mentionné Java, nous travaillons avec .NET.
"envisagez de désactiver les déclencheurs et les contraintes de clé étrangère" i> nous n'avons pas de déclencheurs dans notre configuration. Quoi qu'il en soit, veuillez noter que les déclencheurs sont souvent quelque chose que vous ne pouvez pas passer sans, surtout s'ils effectuent des modifications de données.
"envisager de désactiver les déclencheurs et les contraintes de clé étrangère" i> Les contraintes de clé étrangère peuvent avoir une incidence sur le taux d'insertion des données, mais si vous les désactivez, vous devez les réactiver plus tard ... et la Il est temps de réactiver (et de vérifier) est comparable au temps enregistré lors de l'insertion b>.
"Considérons également la taille du segment de restauration." i> Personne n'a mentionné les transactions. De toute façon ils sont là pour être utilisés. L'engagement @ 1000 records seuils, dans certaines applications, est ridicoleux.
@Teejay, je suis désolé si vous avez mal compris ma réponse. J'ai suggéré une solution beaucoup plus facile à la mondialisation que Nvarchars (qui fonctionne réellement dans n'importe quel environnement Unicode, y compris .NET) et a essayé de résoudre votre problème avec la lenteur. Si ceux-ci ne sont pas pertinents pour vous, n'hésitez pas à ignorer de la question. Pour les enregistrements, les transactions sont i> là tout le temps, même implicitement ou explicitement. J'ai constaté que 1000 transactions commettre sont assez standard dans le chargement en vrac des bases de données Oracle de production, que je travaille au cours des 15 dernières années.
Désolé d'interpréter mal votre réponse et de sous-estimer votre expérience. Veuillez modifier légèrement votre question afin que je puisse supprimer le bowvote (il est verrouillé). Malheureusement, la modification de l'approche n'est pas une option ici. BTW, Insérer dans ... Union Tout code> est assez rapide, du moins pour nos actionnements.
Vous pouvez également lancer si vous connaissez la taille de la colonne cible. Ou votre couche peut supporter un mécanisme d'insertion en vrac approprié. Mais sûrement en utilisant
n '...' code> évite simplement une conversion implicite du littéral lors de l'insertion, de votre jeu de caractères de base de données sur le jeu de caractères national?
@Alexpoole sincère, je ne comprends pas votre question ...
Combien de lignes sont insérées par déclaration? Si
insérer tout code> est plus lent que
Union tout code> Vous pouvez rencontrer un problème d'analyse Oracle, comme expliqué dans ma réponse Ici . Il peut être suffisant de casser le
Insérer tout code> en petits morceaux pour éviter les longues fois d'analyse d'énormes déclarations SQL.
@Jonheller Pour le moment, je définissais la constante de la ligne à la ligne à
100 code>. Avec cette valeur, je peux obtenir 81 000 lignes (x 23 colonnes) insérées dans environ 21 secondes.