トップ «前の日記(2010-03-25) 最新 次の日記(2010-03-27)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2010-03-26

_ rownum

ちょっとしたことで、rownumを使うかrowidを使うかで議論になって、結局はrownum派の勘違いで実はrowidを使うべきという結論となった。

というのは、どうでも良いのだが、その過程でrownumについて、OracleがOTNのそこかしこで、where rownum > 1というのを書くなという注釈を入れまくっていることに気づいて、ちょっと不思議になった。

rownumというのは、Oracleの場合、フェッチしてきたロウに振られる1からの連番で擬似カラムということになる。

rubyの、each_with_indexみたいなものだ。

で、とにかくそこら中に「where rownum > 1」は間違いだからそう書きたければこう書けという注釈を入れている。そういうコラムまである。

そんなにいっぱい注釈が必要なくらい、みんながみんな間違えるということを知っているのなら、なぜ振る舞いを直さないのか? と、とても不思議になる。

それはそれとして、そのバグはおもしろい。

同じことをrubyでできないか考えてみる。

Rubyでリストのフェッチ時にフィルタを入れるには、Enumerable#selectを使うことになるから、ここではselect_with_indexというメソッドを考えることにする。

かつ、以下のように振舞う必要がある。

a = [1, 2, 3, 4].select_with_index do |e, i|
   i > 1
end
p a #=> []
したがって、次のようには実装できない。
module Enumerable
  def select_with_index
    ret = []
    self.each_with_index do |e, i|
      if yield(e, i + 1)  # +1は不要かも 0オリジンでいいよな
        ret << e
      end
    end
    ret
  end
end

これをOracleのrownumと同様にするには、以下のようにすれば良いのか。

module Enumerable
  def select_with_index # oracle's rownum type
    ret = []
    self.each do |e|
      if yield(e, ret.size + 1)  # +1は不要かも 0オリジンでいいよな
        ret << e
      end
    end
    ret
  end
end

簡単に実装できるが、何の役に立つかな?


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|

ジェズイットを見習え