1

我有具有某种唯一约束的 postgresql 表。

我有将更新此表的 ruby​​ 脚本。当发生这种错误时,ruby 脚本应该能够切换到 UPDATE 而不是 INSERT:
PGError: ERROR: duplicate key value violates unique constraint

CMIIW,续集似乎无法捕捉到这个异常??

无论如何,下面的示例代码是我希望看到的,但显然不是:

@myarray.each do |x|
        fresh_ds = DB["INSERT INTO mytable (id, col_foo) values ('#{x}' ,'#{myhash[x]}')"] 
        result = fresh_ds.insert

        catch Sequel::Error do

            fresh_ds = DB["UPDATE mytable set col_foo = '#{myhash[x]} where id = #{x}"]
            result = fresh_ds.update

        end

end

也许我的 ruby​​ 代码是错误的,或者我错过了一些我不知道的东西。
有什么解决办法吗?
谢谢。

更新: 下面的代码有效,当违反唯一约束时会捕获错误。

@myarray.each do |x|
    begin
      # INSERT CODE
    rescue Sequel::Error
      # UPDATE CODE
    end

end
4

2 回答 2

1

解决此问题的另一种方法是使用 Sequel::Model 的find_or_create方法:

find_or_create (cond, &block)

与 find 类似,但在记录不存在时使用给定条件调用 create。与 find 不同的是,此方法中使用的块不传递给 find,而是仅在 find 不返回对象时传递给 create。

于 2011-01-14T19:58:54.643 回答
1

首先,Ruby 中的 try-catch是这样的:

begin
...
rescue ExceptionClass => ex
...
end

另一件事是您应该使用 Sequel 的参数插值而不是手动进行整个查询(主要是因为 SQL 注入):

fresh_ds = DB["INSERT INTO mytable (id, col_foo) values (? ,?)", x, myhash[x]]

PS:

正如其他人已经指出的那样,还有其他可以说更好的方法来执行“插入或更新”。一般来说,异常是指,呃,异常,即在执行过程中通常不应该发生的情况。你的情况比较复杂if,所以我要么先SELECT检查行是否已经存在,要么先尝试UPDATE查看更改的行数,INSERT如果为零则执行。

于 2011-01-13T15:33:20.300 回答