@@ -24,13 +24,11 @@ def exec_insert(sql, name = nil, binds = [], pk = nil, _sequence_name = nil)
2424 end
2525
2626 def exec_delete ( sql , name , binds )
27- sql = sql . dup << '; SELECT @@ROWCOUNT AS AffectedRows'
28- super ( sql , name , binds ) . rows . first . first
27+ super . rows . first . try ( :first ) || super ( "SELECT @@ROWCOUNT As AffectedRows" , "" , [ ] ) . rows . first . try ( :first )
2928 end
3029
3130 def exec_update ( sql , name , binds )
32- sql = sql . dup << '; SELECT @@ROWCOUNT AS AffectedRows'
33- super ( sql , name , binds ) . rows . first . first
31+ super . rows . first . try ( :first ) || super ( "SELECT @@ROWCOUNT As AffectedRows" , "" , [ ] ) . rows . first . try ( :first )
3432 end
3533
3634 def supports_statement_cache?
@@ -108,6 +106,18 @@ def execute_procedure(proc_name, *variables)
108106 yield ( r ) if block_given?
109107 end
110108 result . each . map { |row | row . is_a? ( Hash ) ? row . with_indifferent_access : row }
109+ when :odbc
110+ results = [ ]
111+ raw_connection_run ( sql ) do |handle |
112+ get_rows = lambda do
113+ rows = handle_to_names_and_values handle , fetch : :all
114+ rows . each_with_index { |r , i | rows [ i ] = r . with_indifferent_access }
115+ results << rows
116+ end
117+ get_rows . call
118+ get_rows . call while handle_more_results? ( handle )
119+ end
120+ results . many? ? results : results . first
111121 end
112122 end
113123 end
@@ -206,7 +216,13 @@ def sql_for_insert(sql, pk, id_value, sequence_name, binds)
206216 sql . dup . insert sql . index ( / (DEFAULT )?VALUES/ ) , " OUTPUT INSERTED.#{ quoted_pk } "
207217 end
208218 else
209- "#{ sql } ; SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident"
219+ table = get_table_name ( sql )
220+ id_column = identity_columns ( table . to_s . strip ) . first
221+ if !id_column . blank?
222+ sql . sub ( /\s *VALUES\s *\( / , " OUTPUT INSERTED.#{ id_column . name } VALUES (" )
223+ else
224+ sql . sub ( /\s *VALUES\s *\( / , " OUTPUT CAST(SCOPE_IDENTITY() AS bigint) AS Ident VALUES (" )
225+ end
210226 end
211227 super
212228 end
@@ -282,6 +298,8 @@ def raw_connection_do(sql)
282298 case @connection_options [ :mode ]
283299 when :dblib
284300 @connection . execute ( sql ) . do
301+ when :odbc
302+ @connection . do ( sql )
285303 end
286304 ensure
287305 @update_sql = false
@@ -344,19 +362,25 @@ def raw_connection_run(sql)
344362 case @connection_options [ :mode ]
345363 when :dblib
346364 @connection . execute ( sql )
365+ when :odbc
366+ block_given? ? @connection . run_block ( sql ) { |handle | yield ( handle ) } : @connection . run ( sql )
347367 end
348368 end
349369
350370 def handle_more_results? ( handle )
351371 case @connection_options [ :mode ]
352372 when :dblib
373+ when :odbc
374+ handle . more_results
353375 end
354376 end
355377
356378 def handle_to_names_and_values ( handle , options = { } )
357379 case @connection_options [ :mode ]
358380 when :dblib
359381 handle_to_names_and_values_dblib ( handle , options )
382+ when :odbc
383+ handle_to_names_and_values_odbc ( handle , options )
360384 end
361385 end
362386
@@ -370,10 +394,28 @@ def handle_to_names_and_values_dblib(handle, options = {})
370394 options [ :ar_result ] ? ActiveRecord ::Result . new ( columns , results ) : results
371395 end
372396
397+ def handle_to_names_and_values_odbc ( handle , options = { } )
398+ @connection . use_utc = ActiveRecord ::Base . default_timezone == :utc
399+ if options [ :ar_result ]
400+ columns = lowercase_schema_reflection ? handle . columns ( true ) . map { |c | c . name . downcase } : handle . columns ( true ) . map { |c | c . name }
401+ rows = handle . fetch_all || [ ]
402+ ActiveRecord ::Result . new ( columns , rows )
403+ else
404+ case options [ :fetch ]
405+ when :all
406+ handle . each_hash || [ ]
407+ when :rows
408+ handle . fetch_all || [ ]
409+ end
410+ end
411+ end
412+
373413 def finish_statement_handle ( handle )
374414 case @connection_options [ :mode ]
375415 when :dblib
376416 handle . cancel if handle
417+ when :odbc
418+ handle . drop if handle && handle . respond_to? ( :drop ) && !handle . finished?
377419 end
378420 handle
379421 end
0 commit comments