5 def get_table_name(sql)
6 if sql =~ /^\s*insert\s+into\s+([^\(\s,]+)\s*|^\s*update\s+([^\(\s,]+)\s*/i
8 elsif sql =~ /\bfrom\s+([^\(\s,]+)\s*/i
15 module SqlServer2000ReplaceLimitOffset
17 def replace_limit_offset!(sql, limit, offset, order)
20 start_row = offset + 1
21 end_row = offset + limit.to_i
22 find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
23 whole, select, rest_of_query = find_select.match(sql).to_a
24 if (start_row == 1) && (end_row ==1)
25 new_sql = "#{select} TOP 1 #{rest_of_query}"
30 #removing out stuff before the FROM...
31 rest = rest_of_query[/FROM/i=~ rest_of_query.. -1]
32 #need the table name for avoiding amiguity
33 table_name = LimitHelpers.get_table_name(sql)
34 primary_key = order[/(\w*id\w*)/i]
35 #I am not sure this will cover all bases. but all the tests pass
36 new_order = "ORDER BY #{order}, #{table_name}.#{primary_key}" if order.index("#{table_name}.#{primary_key}").nil?
39 if (rest_of_query.match(/WHERE/).nil?)
40 new_sql = "#{select} TOP #{limit} #{rest_of_query} WHERE #{table_name}.#{primary_key} NOT IN (#{select} TOP #{offset} #{table_name}.#{primary_key} #{rest} #{new_order}) #{order} "
42 new_sql = "#{select} TOP #{limit} #{rest_of_query} AND #{table_name}.#{primary_key} NOT IN (#{select} TOP #{offset} #{table_name}.#{primary_key} #{rest} #{new_order}) #{order} "
52 module SqlServer2000AddLimitOffset
53 def add_limit_offset!(sql, options)
55 order = "ORDER BY #{options[:order] || determine_order_clause(sql)}"
56 sql.sub!(/ ORDER BY.*$/i, '')
57 SqlServerReplaceLimitOffset.replace_limit_offset!(sql, options[:limit], options[:offset], order)
62 module SqlServerReplaceLimitOffset
64 def replace_limit_offset!(sql, limit, offset, order)
67 start_row = offset + 1
68 end_row = offset + limit.to_i
69 find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
70 whole, select, rest_of_query = find_select.match(sql).to_a
72 if rest_of_query[0] == "1"
73 rest_of_query[0] = "*"
75 if rest_of_query[0] == "*"
76 from_table = LimitHelpers.get_table_name(rest_of_query)
77 rest_of_query = from_table + '.' + rest_of_query
79 new_sql = "#{select} t.* FROM (SELECT ROW_NUMBER() OVER(#{order}) AS _row_num, #{rest_of_query}"
80 new_sql << ") AS t WHERE t._row_num BETWEEN #{start_row.to_s} AND #{end_row.to_s}"
87 module SqlServerAddLimitOffset
88 def add_limit_offset!(sql, options)
90 order = "ORDER BY #{options[:order] || determine_order_clause(sql)}"
91 sql.sub!(/ ORDER BY.*$/i, '')
92 SqlServerReplaceLimitOffset.replace_limit_offset!(sql, options[:limit], options[:offset], order)