在sequel/ruby中捕获postgresql异常有困难

在sequel/ruby中捕获postgresql异常有困难,ruby,postgresql,sequel,Ruby,Postgresql,Sequel,我有一个具有某种唯一约束的postgresql表 我有一个更新这个表的ruby脚本。 ruby脚本应该能够切换到UPDATE而不是INSERT 发生此类错误时: PGError:错误:重复的键值违反了唯一约束 CMIIW,续集似乎无法捕捉到这个异常 无论如何,下面的示例代码是我希望看到的,但显然不是: @myarray.each do |x| fresh_ds = DB["INSERT INTO mytable (id, col_foo) values ('#{x}' ,'#{m

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

我有一个更新这个表的ruby脚本。 ruby脚本应该能够切换到UPDATE而不是INSERT 发生此类错误时:
PGError:错误:重复的键值违反了唯一约束

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
首先,在Ruby中尝试catch:

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

附言:


正如其他人已经指出的,还有其他可以说更好的方法来执行“插入或更新”。一般来说,异常是指呃异常,即在执行过程中通常不应该发生的情况。您的情况更多的是
if
排序,因此我会首先使用
SELECT
检查行是否已经存在,或者,首先尝试
更新
,查看更改的行数,并执行
INSERT
,如果行数为零。

解决此问题的替代路径使用Sequel::Model的方法:

查找或创建(cond和block)

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


谢谢,我不知道begin/rescue/end可以在循环中使用,sql注入避免技巧也很受欢迎。更惯用的说法是:
DB[:mytable]。insert:id=>x,:col\u foo=>myhash[x]
然后是
DB[:mytable]。过滤器(:id=>x)。更新(:col\u foo=>myhash[x])
好的,伙计们,我知道这段代码非常脆弱,会修复它的。
begin
...
rescue ExceptionClass => ex
...
end
fresh_ds = DB["INSERT INTO mytable (id, col_foo) values (? ,?)", x, myhash[x]]