5

Я работаю над проектом, где я являюсь разработчиком/администратором базы данных в среде PostgreSQL. Лидер решил использовать Rails для логики приложения и нанял программиста Rails.Вызов хранимых процедур PL/pgSQL из Ruby on Rails

Программист Rails сказал, что он обычно программирует весь код приложения и не любит отсутствие контроля, представленного тем, что кто-то передает ему хранимую процедуру и что он никогда не делал этого в рельсах.

База данных использует много наследования/EERM, поэтому хранимые процедуры и триггеры облегчат работу, в дополнение к преимуществам производительности от использования proc.

У меня есть четыре вопроса:

1) Как вызвать PL/PgSQL хранимую процедуру из Rails без возвращаемого значения

2) Как вызвать PL/PgSQL хранимую процедуру из Rails с одной возвращаемое значение (1 строка/1 столбец)

3) Как вызвать хранимую процедуру pl/pgSQL из Rails с возвращаемым значением столбца 1 строки.

4) Как вызвать хранимую процедуру pl/pgSQL из Rails с использованием параметра OUT?

Спасибо!

+6

Вы будете иметь плохое время, если вы может убедить вашего Rails-программиста использовать что-то вроде [Sequel] (http://sequel.rubyforge.org). По умолчанию Rails ORM (ActiveRecord) не считает, что база данных должна содержать любую логику и не понимает ничего более сложного, чем 'select *' и простых объединений, вы будете бороться с ней все время, если вы нарушаете соглашения используя «причудливые» вещи, такие как триггеры, хранимые процедуры или даже подготовленные заявления. –

+2

Да ... proc и наследование DB + ActiveRecord приведет вас прямо на сайт http://thedailywtf.com/. Вы должны жить с решением пойти на Rails (и, предположительно, его ActiveRecord ORM) и выбросить свой проект БД из окна, а затем создать тот, который следует за контурами ActiveRecord (без глупых вещей, таких как «внешние ключи» или «ограничения», кто же их захочет?). В качестве альтернативы, измените решение и убедитесь, что в качестве заметок Му вы можете получить их, по крайней мере, для использования разумного ORM. –

ответ

7

Здравствуйте Я использую этот код для работы с PgSQL хранимых процедур Это покрывает все, кроме последнего вопроса

class SpActiveRecord < ActiveRecord::Base 

     self.abstract_class = true 
     #without return value 
     def self.execute_sp(sql, *bindings) 
     perform_sp(:execute, sql, *bindings) 
     end 
     #select many return values 
     def self.fetch_sp(sql, *bindings) 
     perform_sp(:select_all, sql, *bindings) 
     end 
     #select single return value 
     def self.fetch_sp_val(sql, *bindings) 
     perform_sp(:select_value, sql, *bindings) 
     end 

     protected 
     def self.perform_sp(method, sql, *bindings) 
     if bindings.any? 
      sql = self.send(:sanitize_sql_array, bindings.unshift(sql)) 
     end 
     self.connection.send(method, sql) 
     end 

    end 

Пример

class Invoice < SpActiveRecord 

def create_or_update 
     raise ReadOnlyRecord if readonly? or !new_record? 

     self.id = fetch_sp_val("SELECT * FROM billing.invoice_generate(?,?,?)", 
           self.account_id, 
           self.start_date, 
           self.end_date) 

     @new_record = false 
     true 
    end 
end