7

我正在做一个项目,我是 PostgreSQL 环境中的数据库设计师/管理员。领导决定使用 Rails 作为应用程序逻辑,并招聘了一名 Rails 程序员。

Rails 程序员说,他通常对所有应用程序代码进行编程,并且不喜欢有人向他传递存储过程所带来的缺乏控制,而且他从未在 Rails 中这样做过。

数据库使用了大量的继承/EERM,因此存储过程和触发器将使他的工作变得更加容易,此外还可以从使用 procs 中获得性能优势。

我有四个问题:

1) 如何从 Rails 调用 pl/pgSQL 存储过程,没有返回值

2) 如何从 Rails 调用具有单个返回值(1 行/1 列)的 pl/pgSQL 存储过程

3) 如何从 Rails 调用具有 1 行多列返回值的 pl/pgSQL 存储过程。

4) 如何使用 OUT 参数从 Rails 调用 pl/pgSQL 存储过程?

谢谢!

4

1 回答 1

9

您好,我正在使用此代码来处理 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
于 2014-03-19T09:35:54.767 回答