Hello all. I am a novice Ruby on Rails programmer, starting my first project using a legacy Oracle 10 database. Using ''reverse_scaffold'' I have created the models/controllers/views for my existing Oracle tables. All seems to work well, using /model/index, /model/show for most of my tables, *except* when one of the tables contains a Oracle ''date'' column, for example when going to ~/filelists/show/959: ActiveRecord::StatementInvalid in FilelistsController#show ArgumentError: invalid date: SELECT * FROM filelist WHERE (filelist.fllid = 959) I already tried updating the record with NULL values for the date columns, or with actual valid date values, but ActiveRecord *or* OracleEnhancedAdapter seems to refuse to load my date values. Is this a known issue or is there something else I should do in my model file to make date support work? Thanks!
Martijn van Rheenen
2009-Sep-14 17:31 UTC
Re: ActiveRecord::StatementInvalid (invalid date) with Oracle
As an extra hint: Can this be caused by a wrongly configured NLS_LANG setting on my Windows client, causing ActiveRecord to get an ''unexpected'' date format back? On Mon, Sep 14, 2009 at 5:03 PM, rheenen <rheenen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hello all. I am a novice Ruby on Rails programmer, starting my first > project using a legacy Oracle 10 database. Using ''reverse_scaffold'' I > have created the models/controllers/views for my existing Oracle > tables. > > All seems to work well, using /model/index, /model/show for most of my > tables, *except* when one of the tables contains a Oracle ''date'' > column, for example when going to ~/filelists/show/959: > > ActiveRecord::StatementInvalid in FilelistsController#show > ArgumentError: invalid date: SELECT * FROM filelist WHERE > (filelist.fllid = 959) > > I already tried updating the record with NULL values for the date > columns, or with actual valid date values, but ActiveRecord *or* > OracleEnhancedAdapter seems to refuse to load my date values. > > Is this a known issue or is there something else I should do in my > model file to make date support work? > > Thanks!--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Cosimo Guglielmucci
2009-Sep-16 10:07 UTC
Re: ActiveRecord::StatementInvalid (invalid date) with Oracle
Martijn van Rheenen wrote:> As an extra hint: Can this be caused by a wrongly configured NLS_LANG > setting on my Windows client, causing ActiveRecord to get an > ''unexpected'' > date format back?Hi Martijn, I''ve the same problem storing in the Date column. I''m using this code( with a mix of italian and english words :D ) in the controller> writing = ValutazioneScorta.create(:Codice => code, :Scorta => scorta,:Data => data ) if code != "" and dataso it''s really embarrassing to read:> DBI::DatabaseError: 23000 (515) [Microsoft][ODBC SQL Server Driver][SQL Server]Impossibile inserire il valore Null nella colonna ''Data, tabella ''giomai_db.dbo.ValutazioneScorta''. La colonna non supporta valori Null. INSERT avrà esito negativo.: INSERT INTO [ValutazioneScorta] ([Scorta], [Data], [CodiceMaietta]) VALUES (5, NULL, ''CNC-1320B008AA'')showing "Null for Data( date ) columns" ( "Null nella colonna ''Data, ..." ) I''m sure that is a framework problem but I can''t say where the value is lost. Error Stack is in attachment! Attachments: http://www.ruby-forum.com/attachment/4042/Full_Trace.txt -- Posted via http://www.ruby-forum.com/.
Cosimo Guglielmucci
2009-Sep-16 10:53 UTC
Re: ActiveRecord::StatementInvalid (invalid date) with Oracle
Of course, overriding the create method( how explained here http://railsruby.blogspot.com/2006/01/activerecordstatementinvalid-in.html ) is not a solution. -- Posted via http://www.ruby-forum.com/.
Cosimo Guglielmucci
2009-Sep-17 08:25 UTC
Re: ActiveRecord::StatementInvalid (invalid date) with Oracle
My horrible but working solution: class UploadController < ApplicationController require ''dbi'' ... def method db=DBI.connect(''dbi:ODBC:giomai_db_dsn'', "sa", ".43tco376") begin ... db.execute("INSERT INTO valutazionescorta values (''#{data}'', ''#{code}'', #{scorta})") if prodotto and scorta and scorta > 0 rescue DBI::DatabaseError => e puts "Errore: #{e.err}" puts "#{e.errstr}" ensure # disconnect from server db.disconnect if db end end end -- Posted via http://www.ruby-forum.com/.
Martijn van Rheenen
2009-Sep-17 10:17 UTC
Re: ActiveRecord::StatementInvalid (invalid date) with Oracle
Wow, that *is* an ugly solution, with all respects.... ;) I still have not found a solution for the original issue with Oracle, somehow retrieval of ''date'' / ''datetime'' values is not working still. I have already tried to set the NLG_LANG environment variable to American, but this did not solve the problem. I will get back to you all with a full stack trace of the error. (meanwhile I reverted back to Symfony / PHP / Doctrine to at least be able to finish my prototype application, but would rather have seen RoR for this project ofcourse) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Martijn van Rheenen
2009-Sep-23 10:45 UTC
Re: ActiveRecord::StatementInvalid (invalid date) with Oracle
As far as I can see now, the problem is in the oracle_enhanced adapter or in ActiveRecord. I created this small Ruby script to test each component: ------------ require ''rubygems'' gem ''ruby-oci8'' require ''oci8'' gem ''activerecord'' gem ''activerecord-oracle_enhanced-adapter'' require ''activerecord'' puts("Testing Oracle OCI gem by selecting record:") OCI8.new(''ccems'', ''ccems'', ''XE'').exec(''SELECT * FROM filelist WHERE (filelist.fllid = 959)'') do |r| puts r.join("\n") end puts("Testing oracle_enhanced installation:") ActiveRecord::Base.establish_connection( :adapter => "oracle_enhanced", :database => "XE", :username => "ccems", :password => "ccems") puts("oracle_enhanced connected succesfully") puts("Testing selection of one record") class Filelist < ActiveRecord::Base set_table_name ''filelist'' set_primary_key ''fllid'' #set_date_columns ''creation_datetime'', ''modification_datetime'', ''firstrecord_datetime'' #ignore_table_columns ''creation_datetime'', ''modification_datetime'', ''firstrecord_datetime'' end filelist = Filelist.find(959); ------------ and, as expected, the very last line returns this error: D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/connection_adapters/abstract_adapter.rb:219:in `log'': ArgumentError: invalid date: SELECT * FROM filelist WHERE (filelist.fllid = 959) (ActiveRecord::StatementInvalid) from D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.1/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb:958:in `select'' from D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in `select_all_without_query_cache'' from D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/connection_adapters/abstract/query_cache.rb:62:in `select_all'' from D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:661:in `find_by_sql'' from D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:1548:in `find_every'' from D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:1583:in `find_one'' from D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:1569:in `find_from_ids'' from D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:616:in `find'' from test.rb:27 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Martijn van Rheenen
2009-Sep-23 14:55 UTC
Re: ActiveRecord::StatementInvalid (invalid date) with Oracle
Finally, I found the error with ''invalid date'' on Oracle 8. Seems that oracle not only allows ''null'' dates, but also ''empty'' dates. On ''empty'' dates, the error would come up! Below is what I changed in oracle_enhanced_oci_connection.rb in lib\ruby\gems\activerecord-oracle_enhanced-adapter-1.2.1\lib\connection_adapters\. The changed lines are marked with #MVR as comment above it. Starts around line 128: # ruby-oci8 1.0 returns OraDate when OraDate # MVR: treat ''empty'' date/time strings as null too! if !(v.hour == 0 && v.minute == 0 && v.second == 0 && v.year == 0 && v.month == 0 && v.day == 0) # RSI: added emulate_dates_by_column_name functionality if OracleEnhancedAdapter.emulate_dates && (v.hour == 0 && v.minute == 0 && v.second == 0) v.to_date else # code from Time.time_with_datetime_fallback begin Time.send(Base.default_timezone, v.year, v.month, v.day, v.hour, v.minute, v.second) rescue offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0 ::DateTime.civil(v.year, v.month, v.day, v.hour, v.minute, v.second, offset) end end end # ruby-oci8 2.0 returns Time or DateTime when Time, DateTime # MVR: treat ''empty'' date/time strings as null too! if !(v.hour == 0 && v.minute == 0 && v.second == 0 && v.year == 0 && v.month == 0 && v.day == 0) if OracleEnhancedAdapter.emulate_dates && (v.hour == 0 && v.min == 0 && v.sec == 0) v.to_date else # recreate Time or DateTime using Base.default_timezone begin Time.send(Base.default_timezone, v.year, v.month, v.day, v.hour, v.min, v.sec) rescue offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0 ::DateTime.civil(v.year, v.month, v.day, v.hour, v.min, v.sec, offset) end end end else v end Hope this is of any help to those fighting with Oracle ;) Cheers On Wed, Sep 23, 2009 at 12:45 PM, Martijn van Rheenen <rheenen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote:> As far as I can see now, the problem is in the oracle_enhanced adapter or > in ActiveRecord. I created this small Ruby script to test each component: > > ------------ > require ''rubygems'' > gem ''ruby-oci8'' > require ''oci8'' > > gem ''activerecord'' > gem ''activerecord-oracle_enhanced-adapter'' > require ''activerecord'' > > puts("Testing Oracle OCI gem by selecting record:") > OCI8.new(''ccems'', ''ccems'', ''XE'').exec(''SELECT * FROM filelist WHERE > (filelist.fllid = 959)'') do > |r| puts r.join("\n") > end > > puts("Testing oracle_enhanced installation:") > ActiveRecord::Base.establish_connection( > :adapter => "oracle_enhanced", :database => "XE", :username => "ccems", > :password => "ccems") > > puts("oracle_enhanced connected succesfully") > > puts("Testing selection of one record") > class Filelist < ActiveRecord::Base > set_table_name ''filelist'' > set_primary_key ''fllid'' > #set_date_columns ''creation_datetime'', ''modification_datetime'', > ''firstrecord_datetime'' > #ignore_table_columns ''creation_datetime'', ''modification_datetime'', > ''firstrecord_datetime'' > end > > filelist = Filelist.find(959); > ------------ > > and, as expected, the very last line returns this error: > > D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/connection_adapters/abstract_adapter.rb:219:in > `log'': ArgumentError: invalid date: SELECT * FROM filelist WHERE > (filelist.fllid = 959) (ActiveRecord::StatementInvalid) > from > D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.1/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb:958:in > `select'' > from > D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in > `select_all_without_query_cache'' > from > D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/connection_adapters/abstract/query_cache.rb:62:in > `select_all'' > from > D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:661:in > `find_by_sql'' > from > D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:1548:in > `find_every'' > from > D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:1583:in > `find_one'' > from > D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:1569:in > `find_from_ids'' > from > D:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:616:in > `find'' > from test.rb:27 > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I don''t know if this could help but I had kind of a similar problem at one point. After much research I ended up coming across a solution by which you can modify in your model the value returned from the DB. You have to override the reader method (code below). This worked for me only when reading values from the table as I had no problem inserting values in it and never inserted a null or empty value but I guess the same could be done with the writer method (dob= in this case): class MyOracleTable < ActiveRecord::Base def dob self[:dob] or ''0001-01-01''.to_date end end Every time that a row is retrieved from the table and the value of DOB is used the model will return the DOB if there is one or an initialized date value. I chose to implement ''0001-01-01'' but it could be anything you want (i.e.: Date.new). I hope this helps. On Sep 14, 11:03 am, rheenen <rhee...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hello all. I am a novice Ruby on Rails programmer, starting my first > project using a legacy Oracle 10 database. Using ''reverse_scaffold'' I > have created the models/controllers/views for my existing Oracle > tables. > > All seems to work well, using /model/index, /model/show for most of my > tables, *except* when one of the tables contains a Oracle ''date'' > column, for example when going to ~/filelists/show/959: > > ActiveRecord::StatementInvalid in FilelistsController#show > ArgumentError: invalid date: SELECT * FROM filelist WHERE > (filelist.fllid = 959) > > I already tried updating the record with NULL values for the date > columns, or with actual valid date values, but ActiveRecord *or* > OracleEnhancedAdapter seems to refuse to load my date values. > > Is this a known issue or is there something else I should do in my > model file to make date support work? > > Thanks!
Martijn van Rheenen
2009-Sep-24 12:30 UTC
Re: ActiveRecord::StatementInvalid (invalid date) with Oracle
Thanks for the tip, pepe... I was optimistic and implemented this in my class: def creation_datetime if (self[:creation_datetime].nil? || self[:creation_datetime].year == 0) ''01-01-1999''.to_date else self[:creation_datetime] end end and it would work perfectly, but it does not help for the problem I encountered, as the values are retrieved from the database *before* this overridden method is called. I still need my fix in the Oracle Enhanced adapter, I''m afraid :| I am now looking into the issue with the developer of the adapter, via the Oracle Enhanced mailing list, as it is a very, very strange error... When I have a final conclusion as to how to prevent this error or propertly fix it in code, I will get back to this list. Meanwhile, here is what I posted on the Oracle Enhanced mailing list about the ''guilty'' date value in my Oracle database that triggers the error: When a date field is NULL in Oracle, it *is* retrieved as ''nil'' by ruby-oci8. So that is working perfectly, also in the Oracle Enhanced code. The problem occurs, when the date field value is not ''nil'' nor filled with a valid date value: it is empty. An ''empty'' date is returned as a datetime with only ''0'' values by OCI8. And this is where the problem occured. I created the following SQL to get a better look at the data of a record that does work, and a record that causes the error: select fllid, creation_datetime , nvl(creation_datetime, Sysdate), length(creation_datetime), to_ char(creation_datetime) from filelist where fllid=959 or fllid=198 It outputs: FLLID creation_datetime nvl() length() to_char() ----- ----------------- ------------------ -------- --------- 198 24-9-2009 13:49:38 959 9 00-000-00 The date with fllid ''198'' works perfectly and is treated as a ''nil'' value by OCI and hence by the Oracle Adapter. The date with fllid ''959'' is the one that will cause problems: As you can see, it IS 9 characters long (???) but it is not ''null'' (indicated by the empty nvl(..) column) and it is displayed as an ''empty'' date just like the date above! Only when converting it to ''char'', the ''0'' values are shown... I tried to create an insert statement that can reproduce a date like this, but have not succeeded so far. I already tried insert statements like this: insert into datatest (id) values (1) -- just inserts as ''NULL'' insert into datatest (id, dt) values (2, '''') -- just inserts as ''NULL'' insert into datatest (id, dt) values (5, to_date(''00/00/0000'',''MM/DD/YYYY'')) -- is not valid insert into datatest (id, dt) values (5, to_date(''01/01/4712 bc'',''DD/MM/YYYY bc'')) -- inserts as normal date insert into datatest (id, dt) VALUES (6, to_date( ''00/00/0000 00:00:00 00'', ''MM/DD/YYYY HH:MI:SS AM'')) -- is not valid So I''m really a bit at a loss here, how this data was inserted at all into the database, as you can imagine. I do know this Oracle 10 database was created by importing (with Oracle''s imp.exe) an export (using Oracle''s exp.exe) from a Oracle 8i database... On Wed, Sep 23, 2009 at 5:10 PM, pepe <Pepe-gUAqH5+0sKL6V6G2DxALlg@public.gmane.org> wrote:> > I don''t know if this could help but I had kind of a similar problem at > one point. After much research I ended up coming across a solution by > which you can modify in your model the value returned from the DB. You > have to override the reader method (code below). This worked for me > only when reading values from the table as I had no problem inserting > values in it and never inserted a null or empty value but I guess the > same could be done with the writer method (dob= in this case): > > class MyOracleTable < ActiveRecord::Base > def dob > self[:dob] or ''0001-01-01''.to_date > end > end > > Every time that a row is retrieved from the table and the value of DOB > is used the model will return the DOB if there is one or an > initialized date value. I chose to implement ''0001-01-01'' but it could > be anything you want (i.e.: Date.new). > > I hope this helps. > > On Sep 14, 11:03 am, rheenen <rhee...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Hello all. I am a novice Ruby on Rails programmer, starting my first > > project using a legacy Oracle 10 database. Using ''reverse_scaffold'' I > > have created the models/controllers/views for my existing Oracle > > tables. > > > > All seems to work well, using /model/index, /model/show for most of my > > tables, *except* when one of the tables contains a Oracle ''date'' > > column, for example when going to ~/filelists/show/959: > > > > ActiveRecord::StatementInvalid in FilelistsController#show > > ArgumentError: invalid date: SELECT * FROM filelist WHERE > > (filelist.fllid = 959) > > > > I already tried updating the record with NULL values for the date > > columns, or with actual valid date values, but ActiveRecord *or* > > OracleEnhancedAdapter seems to refuse to load my date values. > > > > Is this a known issue or is there something else I should do in my > > model file to make date support work? > > > > Thanks! > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---