2010-11-22 20 views
1

Je travaille avec Ruby on Rails 3.0 sur une base de données en lecture seule (connexion via oracle_enhanced_adapter).Rails 3 et Oracle: les paramètres NLS rejettent le séparateur décimal

En cours d'exécution dans le problème connu "n + 1 requêtes" j'ai essayé la méthode includes.
Contrairement à la description dans les guides Rails, la deuxième requête produite répertoriait les ID requis non comme des entiers, mais comme des représentations sous forme de chaîne de valeurs flottantes. Les ID d'origine sont de type NUMBER.

Malheureusement, les paramètres NLS des bases de données sont pour l'Allemagne, y compris le NLS_NUMERIC_CHARACTERS qui attend "," comme séparateur décimal. Donc, je reçois toujours un ORA-01722 erreur as described here.

Plus précisément:

@var.assoc.includes(:another_assoc).where("column_1 = ?", some_value)

rendements

ActiveRecord::StatementInvalid: OCIError: ORA-01722: invalid number: SELECT "TABLE_A".* FROM "TABLE_A" WHERE ("TABLE_A"."ID" IN ('1715.0','1716.0','1717.0','1718.0','1719.0','1720.0','1721.0'))

(je devais simplifier le code ferroviaire ci-dessus, car il contenait des détails distrayants comme les conversions "string au symbole")

Comme mentionné la base de données est en lecture seule, donc en utilisant

alter session set nls_numeric_characters = '.,' 

travaillé directement sur la base de données. Mais je n'étais pas capable de trouver la bonne façon de modifier la session des rails.

Tout ce que j'ai trouvé semblait se référer à Rails 2 ou utilisé des fonctions obsolètes.
Comment puis-je résoudre ceci pour Rails 3.0?

Alternativement: Comment puis-je forcer Rails (ou peut-être l'oracle_enhanced_adapter) à convertir tous les identifiants listés en Fixnum?

Merci et meilleures salutations, Tim

+0

Bonjour Tim, bienvenue sur stackoverflow. Pourriez-vous s'il vous plaît poster le code de rails générant cette déclaration? – Patrick

Répondre

1

Nous avons eu le même problème avec Oracle, et nous avons résolu en plaçant le code suivant dans un initialiseur (placez-le dans config/initializers/something.rb):

BigDecimal.class_eval do 
    alias :old_to_s :to_s 

    def to_s(format='F') 
    old_result = self.old_to_s(format) 
    (old_result[-2..-1] == ".0" ? old_result[0..-3] : old_result) 
    end 
end 

Il est causée par le type de colonne que vous utilisez comme clé primaire. Si vous le déclarez comme NUMBER, il sera converti en BigDecimal. Alternativement, vous pouvez déclarer vos ID comme NUMBER(10) ou quelque chose de similaire qui serait plus évidemment mapper à un FixNum (dont l'identifiant sera converti correctement).

Espérons que cela aide.

+0

merci les gars, vous êtes génial :-) – bunter