【问题标题】:SQL merge to prevent double voting on a pollSQL 合并以防止对投票进行双重投票
【发布时间】:2012-07-16 21:45:47
【问题描述】:

我正在开发一个投票应用程序。 SQL 架构是:

polls -> * options (poll_id) -> * answers (option_id)

或者:“投票有很多选项,选项可以有答案(又名投票)”

我只能允许每个用户每次投票投一票。这是合并子句(显然不起作用):

  merge into answers
  using (select count(*)
         from answers, options, polls
         where answers.option_id = options.id
         and options.poll_id = polls.id
         and polls.id = {poll_id}
         and answers.owner_id = {owner_id}) votes
  on (votes = 0)
  when matched then
  insert into answers values (NULL, {option_id}, {owner_id}, NOW())

【问题讨论】:

  • now() 不是有效的 Oracle 函数。
  • 是的,这个查询来自我们使用 H2 的开发服务器。我需要它与 11g 一起使用,如果没有标准 SQL,我可以在 dev 上填充该方法或任何东西
  • 这些主键上有什么样的索引?
  • 也许您应该使用带有 NOT IN 的子查询?

标签: sql merge


【解决方案1】:

如果您从不想更新,那么应该做一个简单的插入。我认为根本不需要合并:

insert into answers (some_value, option_id, owner_id, last_modified)
select null, {option_id}, {owner_id}, current_timestamp
from dual
where not exists (select 1 
                  from answers a
                    join options o on o.id = a.option_id
                    join polls p on p.id = o.poll_id
                  where a.owner_id = {owner_id}
                    and p.id = {polls_id}

我明确列出了插入子句的列,因为不这样做是不好的编码风格。我当然只是猜到了你的列名,因为你没有向我们展示你的表定义。

【讨论】:

  • 这看起来几乎是标准的 sql,除了 dual。没有解决方法吗? :)
  • @PabloFernandez:不,不是真的。因为Oracle和H2太不一样了。但是我认为如果进入Oracle兼容模式,H2支持双表。
  • @PabloFernandez:我错了。 H2 不支持这些兼容模式。我把它和 HSQLDB 弄混了。
【解决方案2】:

试试这个:

MERGE INTO answers
USING 
(SELECT options.id 
             FROM options, polls
             WHERE options.poll_id = polls.id
             AND polls.id = {poll_id}
) options
ON (answers.option_id = options.id AND answers.owner_id = {owner_id})
WHEN NOT MATCHED THEN
    INSERT INTO answers VALUES (NULL, {option_id}, {owner_id}, SYSDATE)
WHEN MATCHED THEN
    -- Do what you need to do for an update

【讨论】:

  • @a_horse_with_no_name OOPS.. 刚刚用 SYSDATE 替换现在忘记了()
猜你喜欢
  • 2012-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多