2010-11-22 2 views
1

Ich arbeite mit Ruby on Rails 3.0 auf einer schreibgeschützten Oracle-Datenbank (Verbindung über oracle_enhanced_adapter).Rails 3 und Oracle: NLS Einstellungen weisen das Dezimaltrennzeichen zurück

In das bekannte "n + 1 Abfragen" Problem gerannt habe ich die Includes-Methode versucht.
Abweichend von der Beschreibung in den Rails-Handbüchern wurden in der produzierten zweiten Abfrage die erforderlichen IDs nicht als Ganzzahlen, sondern als Zeichenfolgendarstellungen von Gleitkommawerten aufgelistet. Die ursprünglichen IDs sind vom Typ NUMBER.

Leider sind die Datenbanken NLS-Einstellungen für Deutschland, einschließlich der NLS_NUMERIC_CHARACTERS, erwartet "," als Dezimaltrennzeichen. So bekomme ich immer einen ORA-01722 Fehler as described here.

Genauer gesagt:

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

Ausbeuten

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'))

(Ich hatte die Bahn Code oben zu vereinfachen, da es einige störende Details wie "string auf das Symbol" enthalten Umwandlungen)

Wie erwähnt, ist die Datenbank readonly, also

alter session set nls_numeric_characters = '.,' 

arbeitete direkt in der Datenbank. Aber ich war nicht in der Lage, den richtigen Weg zu finden, um die Rails-Session zu ändern.

Alles, was ich gefunden habe, schien sich auf Rails 2 zu beziehen oder veraltete Funktionen zu verwenden.
Wie kann ich das für Rails 3.0 lösen?

Alternativ: Wie kann ich Rails (oder vielleicht den oracle_enhanced_adapter) zwingen, alle aufgeführten IDs in Fixnum umzuwandeln?

Danke und viele Grüße, Tim

+0

Hallo Tim, willkommen zu stackoverflow. Könnten Sie bitte den Rails-Code posten, der diese Aussage generiert? – Patrick

Antwort

1

Wir hatten das gleiche Problem Oracle verwenden, und wir lösen es durch den folgenden Code in ein initializer platzieren (legen Sie sie in 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 

Es wird durch den Spaltentyp verursacht, den Sie als Primärschlüssel verwenden. Wenn Sie es als NUMBER deklarieren, wird es in eine BigDecimal konvertiert. Alternativ könnten Sie Ihre IDs als NUMBER(10) oder etwas Ähnliches deklarieren, was deutlicher zu einem FixNum (dessen IDs korrekt konvertiert werden) würde.

Hoffe, das hilft.

+0

danke Jungs, du bist großartig :-) – bunter

Verwandte Themen