2016-03-03 106 views
1

我目前有這個工作,但必須有更好的方法。我有一個模型,用於查詢外部oracle數據庫視圖。在這種特殊情況下,我必須對每個id值運行一個查詢,並將這些結果組合到一個數組中。結合ActiveRecord ::結果.each循環

這可以工作,但它需要在數組上進行相當多的維護才能以更易於使用的格式獲取信息。希望有一種方法來簡化這個:

def self.count_by_year(ids, year) 
    start_date = DateTime.strptime(year.to_s, "%Y").strftime("%Y%m%d") 
    end_date = DateTime.strptime(year.to_s, "%Y").end_of_year.strftime("%Y%m%d") 
    bulk_issues = [] 
    if ids.size > 1 
     ids.each do |uc| 
     bulk_issues << (External.connection.select_all "SELECT COUNT(*) FROM DB WHERE ID='#{uc.id}' AND GROUP_NAME != 'CA' AND STATUS != 'Cancelled' AND (DATE_OPENED BETWEEN '#{start_date}' AND '#{end_date}')") 
     end 
    else 
     bulk_issues << (External.connection.select_all "SELECT COUNT(*) FROM DB WHERE ID='#{ids.first.id}' AND GROUP_NAME != 'CA' AND STATUS != 'Cancelled' AND (DATE_OPENED BETWEEN '#{start_date}' AND '#{end_date}')") 
    end 
    return bulk_issues 
    end 

當叫這個返回如下:

[#<ActiveRecord::Result:0x007fdafd95ec20 @columns=["count(*)"], @rows=[[51]], @hash_rows=nil, @column_types={}>, #<ActiveRecord::Result:0x007fdafd95d320 @columns=["count(*)"], @rows=[[19]], @hash_rows=nil, @column_types={}>] 

當扁平返回:

[{"count(*)"=>51}, {"count(*)"=>19}] 

這是一種痛苦提取數據因爲我必須將這些值拉出來並將它們放入一個新的數組中,以便將其格式化爲我正在使用的值。

我所試圖做的就是功能的陣列中返回數據如下:

[51, 19] 

任何幫助將不勝感激!

+0

您在進行原始查詢時要特別小心,以避免在查詢中注入任何有害內容。使用佔位符使這些顯着更安全。 – tadman

回答

1

嘛,一開始,Oracle supports IN expressions,所以不是你ids.each...只是做:

bulk_issues = External.connection.select_all "SELECT COUNT(*) FROM DB WHERE ID IN (#{ids.map{|id| "'#{id.id}'"}.join(",")}) AND GROUP_NAME != 'CA' AND STATUS != 'Cancelled' AND (DATE_OPENED BETWEEN '#{start_date}' AND '#{end_date}')" 

所以那麼這將不會是一個數組,它只會像{"count(*)"=>70}哈希,因此要獲得只是70指出通話:

*, count = bulk_issues.first 

所以添加AS到您的查詢,所以我們可以肯定就是我們的哈希將返回,你的整個方法變爲:

def self.count_by_year(ids, year) 
    start_date = DateTime.strptime(year.to_s, "%Y").strftime("%Y%m%d") 
    end_date = DateTime.strptime(year.to_s, "%Y").end_of_year.strftime("%Y%m%d") 

    res = External.connection.select_all("SELECT COUNT(*) AS count FROM DB WHERE ID IN (#{ids.map{|id| "'#{id.id}'"}.join(",")}) AND GROUP_NAME != 'CA' AND STATUS != 'Cancelled' AND (DATE_OPENED BETWEEN '#{start_date}' AND '#{end_date}')") 

    return res.to_hash.first['count'].to_i 
end 
+0

對不起,幾個編輯,現在完成:) – smathy

+0

謝謝!我會盡快給它一個回報,並回報 – willfore

+1

這很好!再次感謝! :) – willfore