在sequel/ruby中捕获postgresql异常有困难
我有一个具有某种唯一约束的postgresql表 我有一个更新这个表的ruby脚本。 ruby脚本应该能够切换到UPDATE而不是INSERT 发生此类错误时:在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
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]]