В JRuby с помощью адаптера JDBC вы можете переопределить вставку и передать в возвращаемом предложении. Сложность заключается в том, что вы не всегда знаете, что такое первичный ключ на этом уровне, поэтому вам, возможно, придется использовать ROWID или запросить все столбцы обратно.
В итоге вы получите что-то похожее на это:
module Sequel
module JDBC
class Database
def execute_insert_with_returning(conn, sql, opts = {})
columns = opts[:key_columns] || ["ROWID"]
q = "{ call #{sql} returning #{columns.join(',')} into #{columns.collect {|_| '?'}.join(',')} }"
stmt = conn.prepare_call(q)
raise "Unable to prepare call for insert" if stmt.nil?
begin
columns.each_with_index do |_, index|
stmt.registerOutParameter(index+1, JavaSQL::Types::VARCHAR)
end
return nil if 0 == stmt.executeQuery
values = (1..columns.count).inject({}) do |memo, index|
key = columns[index-1].downcase.to_sym rescue nil
memo[key] = stmt.get_string(index) unless key.nil?
memo
end
values
ensure
stmt.close
end
end # #execute_insert_with_returning
alias execute_without_specialized_insert execute
def execute(sql, opts={}, &block)
if opts[:type] == :insert
synchronize(opts[:server]) do |conn|
execute_insert_with_returning conn, sql, opts
end
else
execute_without_specialized_insert sql, opts, &block
end
end # #execute
end # Database
end # JDBC
end # Sequel
Я сделал что-то вроде этого, и это работает очень хорошо. Я думаю, нам также пришлось переопределить Sequel::Model, чтобы он передал первичный ключ как opts[:key_columns], но я могу неправильно помнить.
Это немного несущий кладж, который выполняет свою работу. Было бы более элегантно специализировать его для адаптера JDBC Oracle и гарантировать, что весь код обработки ошибок присутствует в исходном операторе выполнения. Учитывая время, я хотел бы получить что-то лучше и вернуть его проекту Sequel.
person
sdeming
schedule
16.09.2011