Skip to content

Commit da13293

Browse files
committed
Allow adapter to return multipe results sets, for example from stored procedures. Fixes issue #29.
1 parent 0368093 commit da13293

File tree

3 files changed

+41
-12
lines changed

3 files changed

+41
-12
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
MASTER
33

4+
* Allow adapter to return multipe results sets, for example from stored procedures. [Chris Hall]
5+
46

57
* 2.3.4
68

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ def run_with_isolation_level(isolation_level)
394394
end
395395

396396
def select_rows(sql, name = nil)
397-
raw_select(sql,name).last
397+
raw_select(sql,name).first.last
398398
end
399399

400400
def execute(sql, name = nil, &block)
@@ -410,7 +410,11 @@ def execute_procedure(proc_name, *variables)
410410
vars = variables.map{ |v| quote(v) }.join(', ')
411411
sql = "EXEC #{proc_name} #{vars}".strip
412412
select(sql,'Execute Procedure',true).inject([]) do |results,row|
413-
results << row.with_indifferent_access
413+
if row.kind_of?(Array)
414+
results << row.inject([]) { |rs,r| rs << r.with_indifferent_access }
415+
else
416+
results << row.with_indifferent_access
417+
end
414418
end
415419
end
416420

@@ -824,7 +828,15 @@ def auto_reconnected?
824828

825829
def select(sql, name = nil, ignore_special_columns = false)
826830
repair_special_columns(sql) unless ignore_special_columns
827-
fields, rows = raw_select(sql,name)
831+
fields_and_row_sets = raw_select(sql,name)
832+
final_result_set = fields_and_row_sets.inject([]) do |rs,fields_and_rows|
833+
fields, rows = fields_and_rows
834+
rs << zip_fields_and_rows(fields,rows)
835+
end
836+
final_result_set.many? ? final_result_set : final_result_set.first
837+
end
838+
839+
def zip_fields_and_rows(fields, rows)
828840
rows.inject([]) do |results,row|
829841
row_hash = {}
830842
fields.each_with_index do |f, i|
@@ -859,24 +871,28 @@ def do_execute(sql,name=nil)
859871

860872
def raw_select(sql, name = nil)
861873
handle = raw_execute(sql,name)
862-
fields = handle.columns(true).map{|c|c.name}
863-
results = handle_as_array(handle)
864-
rows = results.inject([]) do |rows,row|
865-
row.each_with_index do |value, i|
866-
if value.is_a? ODBC::TimeStamp
867-
row[i] = value.to_sqlserver_string
874+
fields_and_row_sets = []
875+
loop do
876+
fields = handle.columns(true).map{|c|c.name}
877+
results = handle_as_array(handle)
878+
rows = results.inject([]) do |rows,row|
879+
row.each_with_index do |value, i|
880+
if value.is_a? ODBC::TimeStamp
881+
row[i] = value.to_sqlserver_string
882+
end
868883
end
884+
rows << row
869885
end
870-
rows << row
886+
fields_and_row_sets << [fields,rows]
887+
finish_statement_handle(handle) && break unless handle.more_results
871888
end
872-
return fields, rows
889+
fields_and_row_sets
873890
end
874891

875892
def handle_as_array(handle)
876893
array = handle.inject([]) do |rows,row|
877894
rows << row.inject([]){ |values,value| values << value }
878895
end
879-
finish_statement_handle(handle)
880896
array
881897
end
882898

test/cases/execute_procedure_test_sqlserver.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,16 @@ def setup
2929
end if sqlserver_2000?
3030
end
3131

32+
should 'allow multiple result sets to be returned' do
33+
results1, results2 = @klass.execute_procedure('sp_helpconstraint','accounts')
34+
assert_instance_of Array, results1
35+
assert_instance_of HashWithIndifferentAccess, results1.first
36+
assert results1.first['Object Name']
37+
assert_instance_of Array, results2
38+
assert_instance_of HashWithIndifferentAccess, results2.first
39+
assert results2.first['constraint_name']
40+
assert results2.first['constraint_type']
41+
end
42+
3243

3344
end

0 commit comments

Comments
 (0)