我希望创建一个存储过程(在plpgsql,PostgreSQL 9.1中),首先检查以确保要插入的记录在其四个列上是唯一的,或者如果更新了记录,则将其更新为唯一值.
Example:
Record (1,2,3,4) is to be inserted.
If Record (1,2,3,4) already exists, then do not insert a duplicate record.
if Record (1,2,3,4) does not exist, then insert it.
Record (1,2,3,4) is to be updated to (5,6,7,8).
If Record (5,6,7,8) already exists, then do not update the record. (duplicate record not allowed).
If Record (5,6,7,8) does not exist, then update the record to the new values.
Run Code Online (Sandbox Code Playgroud)
我之前在记录的字段上使用过唯一索引,但是想了解如何编写触发器来完成此操作.
我有以下代码:
rating = user.recipe_ratings.where(:recipe_id => recipe.id).where(:delivery_id => delivery.id).first_or_create
Run Code Online (Sandbox Code Playgroud)
然而不知何故,我们偶尔会遇到PG::Error: ERROR: duplicate key value violates unique constraint
错误。我想不出任何应该发生的原因,因为重点first_or_create
是防止这些情况发生。
这只是一个疯狂的竞争条件吗?我怎样才能在没有一系列令人发狂的begin...rescue
块的情况下解决这个问题?
postgresql activerecord race-condition select-insert ruby-on-rails-3
我有一个第三方应用程序连接到我的PostgreSQL数据库中的视图。它要求视图具有主键,但不能处理UUID类型(这是视图的主键)。如果将UUID用作视图中的文本,它也不能将UUID作为主键。
我想做的就是将UUID转换为数字,然后将其用作主键。然而,
SELECT x'14607158d3b14ac0b0d82a9a5a9e8f6e'::bigint
Run Code Online (Sandbox Code Playgroud)
由于数字超出范围而失败。
因此,我想使用SQL占用UUID的大部分,并创建一个int8 / bigint。我应该澄清,维持秩序是“合乎需要的”,但我知道这样做会改变某些秩序。
我试过了:
SELECT x(substring(UUID::text from 1 for 16))::bigint
Run Code Online (Sandbox Code Playgroud)
但是用于转换十六进制的x运算符似乎不喜欢方括号。我将其抽象为一个函数,但是
SELECT hex_to_int(substring(UUID::text from 1 for 16))::bigint
Run Code Online (Sandbox Code Playgroud)
仍然失败。
如何从UUID的“大头”部分得到bigint?
我正在使用Spring和PostgreSQL,我尝试使用如下代码进行一种UPSERT:
jt.update("delete from A where id = 1")
jt.update("insert into A (id, value) values (1, 100)")
Run Code Online (Sandbox Code Playgroud)
包含在事务中(使用@Transactional
).
问题是,当有很多并发请求时,此代码会因"重复键"错误而失败,这意味着事务不是孤立的,或者......
我错过了有关交易如何运作的信息吗?我应该在这里使用不同的机制(例如线程同步)吗?
postgresql ×4
activerecord ×1
casting ×1
constraints ×1
database ×1
plpgsql ×1
spring ×1
sql ×1
triggers ×1
types ×1
uuid ×1