2017-01-31 81 views
8

Mam następujący kod, który wykonuje widokiem Oracle w następujący sposób:Ruby on Rails przygotowane oświadczenie do widoku Oracle/funkcja

def run_query 
    connection.exec_query(
     "SELECT * FROM TABLE(FN_REQRESP(#{type_param}, 
             #{search_type_param}, 
             #{tid_param}, 
             #{last_param}, 
             #{key_param}, 
             #{tran_id_param}, 
             #{num_param}, 
             #{start_date_param}, 
             #{end_date_param}))") 
end 

Wyjście powyższego zapytania jest następująca:

SELECT * FROM TABLE(FN_REQRESP('ALL', 
'ALL_TRAN', 
'100007', 
'', 
'', 
'', 
'', 
TO_DATE('27-January-2017','dd-MON-yy'), 
TO_DATE('31-January-2017','dd-MON-yy'))) 

Problem polega na tym, że powyższe zapytanie ma lukę SQL injection.

Tak, próbowałem dodać przygotować oświadczenie w następujący sposób:

connection.exec_query('SELECT * FROM TABLE(FN_REQRESP(?,?,?,?,?,?,?,?,?))','myquery',[type_param,search_type_param,tid_param,last_param,key_param,tran_id_param,num_param,start_date_param,end_date_param]) 

pojawia się następujący błąd now:

NoMethodError: undefined method `type' for "'ALL'":String: SELECT * FROM TABLE(FN_REQRESP(?,?,?,?,?,?,?,?,?))

To pojedyncze cytaty, które brudząc ją wierzę. Czy istnieje sposób na pokonanie tego?

EDIT: Próbowałem odpowiedź NDN i błąd poniżej:

OCIError: ORA-00907: missing right parenthesis: SELECT * FROM TABLE(FN_REQRESP('\'ALL\'', 
             '\'ALL_TRAN\'', 
             '\'100007\'', 
             '\'\'', 
             '\'\'', 
             '\'\'', 
             '\'\'', 
             'TO_DATE(\'01-February-2017\',\'dd-MON-yy\')', 
             'TO_DATE(\'10-February-2017\',\'dd-MON-yy\')')) 
+0

może to głupie pytanie, i jest potrzebne dla wyroczni, ale czy próbowałeś usunąć "[" i "]"? dla mnie wygląda na to, że próbujesz podać drugi? tablica, również prawdopodobnie o nazwie zmiennych wiążących byłaby dobrym pomysłem: http://millarian.com/rails/quick-tip-rails-named-bind-variables/ –

+0

Tak, próbowałem usunąć [] i dostałem to ArgumentError : zła liczba argumentów (11 za 3) – Micheal

+0

również nie mogę używać nazwanych zmiennych bind, ponieważ jest to funkcja Oracle i nie znam nazw kolumn. Wiem tylko, jakie parametry mogę przekazać – Micheal

Odpowiedz

3

Patrząc the source, binds zostanie odlany w jakiś magiczny sposób i trzeba zdać nazwie prepare: true argumentu, jak również.

Zwykle też działało inaczej w older versions.


Aby zaoszczędzić sobie kłopotu, wystarczy użyć #sanitize:

params = { 
    type:  type_param, 
    search_type: search_type_param, 
    tid:   tid_param, 
    last:  last_param, 
    key:   key_param, 
    tran_id:  tran_id_param, 
    num:   num_param, 
    start_date: start_date_param, 
    end_date: end_date_param, 
} 

params.each do |key, param| 
    params[key] = ActiveRecord::Base.sanitize(param) 
end 

connection.exec_query(
    "SELECT * FROM TABLE(FN_REQRESP(#{params[:type]}, 
            #{params[:search_type]}, 
            #{params[:tid]}, 
            #{params[:last]}, 
            #{params[:key]}, 
            #{params[:tran_id]}, 
            #{params[:num]}, 
            #{params[:start_date]}, 
            #{params[:end_date]}))" 
) 
+0

ndn, próbowałem Twojego rozwiązania, ale dostałem błąd. Aby uzyskać błąd, zobacz EDYCJA do oryginalnego wpisu u dołu. – Micheal

0

ten nazywany jest przygotowane oświadczenie. W doc można znaleźć przykład, jak z niego korzystać.

+0

Nie widzę, jak mogę użyć przygotowanej składni instrukcji w moim przykładzie. – Micheal