Skip to content

Commit d1da452

Browse files
committed
Merge pull request #77 from rsim/fix-dbms-output-in-case-of-exception
Fix dbms output in case of exception
2 parents 135b10e + 7ea55c8 commit d1da452

File tree

2 files changed

+36
-34
lines changed

2 files changed

+36
-34
lines changed

lib/plsql/procedure_call.rb

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ def exec
2626

2727
@cursor.exec
2828

29-
dbms_output_log
30-
3129
if block_given?
3230
yield get_return_value
3331
nil
@@ -36,6 +34,7 @@ def exec
3634
end
3735
ensure
3836
@cursor.close if @cursor
37+
dbms_output_log
3938
end
4039

4140
private
@@ -215,10 +214,8 @@ def construct_sql(args)
215214
end
216215
add_out_variables
217216

218-
dbms_output_enable_sql, dbms_output_get_sql = dbms_output_sql
219-
220217
@sql = @declare_sql.empty? ? "" : "DECLARE\n" << @declare_sql
221-
@sql << "BEGIN\n" << @assignment_sql << dbms_output_enable_sql << @call_sql << dbms_output_get_sql << @return_sql << "END;\n"
218+
@sql << "BEGIN\n" << @assignment_sql << dbms_output_enable_sql << @call_sql << @return_sql << "END;\n"
222219
end
223220

224221
def add_argument(argument, value, argument_metadata=nil)
@@ -539,49 +536,46 @@ def procedure_name
539536
@procedure_name ||= @procedure.procedure
540537
end
541538

542-
def dbms_output_sql
543-
if @dbms_output_stream
544-
dbms_output_enable_sql = "DBMS_OUTPUT.ENABLE(#{@schema.dbms_output_buffer_size});\n"
545-
# if database version is at least 10.2 then use DBMS_OUTPUT.GET_LINES with SYS.DBMSOUTPUT_LINESARRAY
546-
if (@schema.connection.database_version <=> [10, 2, 0, 0]) >= 0
547-
@declare_sql << "l_dbms_output_numlines INTEGER := #{Schema::DBMS_OUTPUT_MAX_LINES};\n"
548-
dbms_output_get_sql = "DBMS_OUTPUT.GET_LINES(:dbms_output_lines, l_dbms_output_numlines);\n"
549-
@bind_values[:dbms_output_lines] = nil
550-
@bind_metadata[:dbms_output_lines] = {:data_type => 'TABLE', :data_length => nil,
551-
:sql_type_name => "SYS.DBMSOUTPUT_LINESARRAY", :in_out => 'OUT'}
552-
# if database version is less than 10.2 then use individual DBMS_OUTPUT.GET_LINE calls
553-
else
554-
dbms_output_get_sql = ""
555-
end
556-
[dbms_output_enable_sql, dbms_output_get_sql]
557-
else
558-
["", ""]
559-
end
539+
def dbms_output_enable_sql
540+
@dbms_output_stream ? "DBMS_OUTPUT.ENABLE(#{@schema.dbms_output_buffer_size});\n" : ""
560541
end
561542

562-
def dbms_output_log
543+
def dbms_output_lines
544+
lines = []
563545
if @dbms_output_stream
564-
# if database version is at least 10.2 then :dbms_output_lines output bind variable has dbms_output lines
565-
if @bind_metadata[:dbms_output_lines]
566-
@cursor[':dbms_output_lines'].each do |line|
567-
@dbms_output_stream.puts "DBMS_OUTPUT: #{line}" if line
568-
end
569-
# if database version is less than 10.2 then use individual DBMS_OUTPUT.GET_LINE calls
546+
if (@schema.connection.database_version <=> [10, 2, 0, 0]) >= 0
547+
cursor = @schema.connection.parse("BEGIN DBMS_OUTPUT.GET_LINES(:dbms_output_lines, :dbms_output_numlines); END;\n")
548+
cursor.bind_param(':dbms_output_lines', nil,
549+
:data_type => 'TABLE',
550+
:data_length => nil,
551+
:sql_type_name => "SYS.DBMSOUTPUT_LINESARRAY",
552+
:in_out => 'OUT')
553+
cursor.bind_param(':dbms_output_numlines', Schema::DBMS_OUTPUT_MAX_LINES, :data_type => 'NUMBER', :in_out => 'IN/OUT')
554+
cursor.exec
555+
lines = cursor[':dbms_output_lines']
556+
cursor.close
570557
else
571558
cursor = @schema.connection.parse("BEGIN sys.dbms_output.get_line(:line, :status); END;")
572559
while true do
573560
cursor.bind_param(':line', nil, :data_type => 'VARCHAR2', :in_out => 'OUT')
574561
cursor.bind_param(':status', nil, :data_type => 'NUMBER', :in_out => 'OUT')
575562
cursor.exec
576563
break unless cursor[':status'] == 0
577-
@dbms_output_stream.puts "DBMS_OUTPUT: #{cursor[':line']}"
564+
lines << cursor[':line']
578565
end
579566
cursor.close
580567
end
581-
@dbms_output_stream.flush
582568
end
569+
lines
570+
end
571+
572+
def dbms_output_log
573+
dbms_output_lines.each do |line|
574+
@dbms_output_stream.puts "DBMS_OUTPUT: #{line}" if line
575+
end
576+
@dbms_output_stream.flush if @dbms_output_stream
583577
end
584578

585579
end
586580

587-
end
581+
end

spec/plsql/schema_spec.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,13 @@ class TestModel < TestBaseModel
227227
before(:all) do
228228
plsql.connection = get_connection
229229
plsql.execute <<-SQL
230-
CREATE OR REPLACE PROCEDURE test_dbms_output(p_string VARCHAR2)
230+
CREATE OR REPLACE PROCEDURE test_dbms_output(p_string VARCHAR2, p_raise_error BOOLEAN := false)
231231
IS
232232
BEGIN
233233
DBMS_OUTPUT.PUT_LINE(p_string);
234+
IF p_raise_error THEN
235+
RAISE_APPLICATION_ERROR(-20000 - 12, 'Test Error');
236+
END IF;
234237
END;
235238
SQL
236239
plsql.execute <<-SQL
@@ -272,6 +275,11 @@ class TestModel < TestBaseModel
272275
expect(@buffer.string).to eq("DBMS_OUTPUT: test_dbms_output\n")
273276
end
274277

278+
it "should log output to specified stream in case of exception" do
279+
expect { plsql.test_dbms_output("test_dbms_output", true) }.to raise_error /Test Error/
280+
expect(@buffer.string).to eq("DBMS_OUTPUT: test_dbms_output\n")
281+
end
282+
275283
it "should not log output to stream when output is disabled" do
276284
plsql.test_dbms_output("enabled")
277285
plsql.dbms_output_stream = nil

0 commit comments

Comments
 (0)