Mittwoch, 13. Juli 2011

Oracle Tabelle in einen anderen Tablespace verschieben

Das Verschieben einer Tabelle von einem Tablespace in einem anderen sollte nur in Ausnahmefällen erfolgen. Dies kann z.B. notwendig sein, wenn die Performance drastisch sinkt. Sämtliche Indizes dieser Tabelle werden gelöscht und müssen neu erstellt werden.

alter table [schema].[ursprungs_tabelle] move tablespace [ziel_tablespace];

Die Indizes müssen neu gebildet werden.

alter index [schema].[index]  rebuild;

Donnerstag, 7. Juli 2011

Rails Migrations mit Oracle Enhanced Adapter

Da Oracle für verschiedene numerische Datentypen nur den Datentyp NUMBER kennt, kann dies zu Problemen führen, wenn eine Rails-Applikation auf eine bereits bestehende Datenbank zurückgreift. Wird eine neue Tabelle mit Hilfe von Migrations angelegt, werden die Datentypen wie folgt zugewiesen:
 :boolean => number(1)  
 :integer => number(38)  
 :float => number  
 :decimal => decimal  

Sind Integer-Werte in der bestehenden Datenbank mit NUMBER ohne Grössenangabe definiert, werden diese in der Rails-Applikation standardmässig als BigDecimal behandelt. Dies kann sich fehlerhaft auf die Applikation auswirken (Darstellungsprobleme, Vergleichsabfragen etc.).

Um das Problem zu lösen, können verschiedene Ansätze gewählt werden:

Wenn möglich, sollte der Datentyp auf der Datenbank angepasst werden (z.B. NUMBER(12)).
Mit der Option
 emulate_integers_by_column_name  
kann eingestellt werden, dass alle Datenbankfelder, welche auf ID enden, in der Applikation als Fixnum behandelt werden. Dazu kann die Datei config/initializers/oracle_enhanced.rb angelegt und mit folgendem Code abgefüllt werden:
 ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true  

Um die Einstellungen global zu ändern, kann die Methode is_integer_column aus der Klasse OracleEnhancedAdapter überschrieben werden.

Müssen nur spezifische Attribute angepasst werden, können für diese im Model die Getter-Methode überschrieben werden.
 def attr   
  self[:attr].to_i if self[:attr].kinf_of? Numeric   
  self[:attr]  
 end