我在我的数据库中有这个功能:
CREATE OR REPLACE FUNCTION "insertarNuevoArticulo"(nombrearticulo character varying, descripcion text, idtipo integer, idfamilia bigint, artstock integer, minstock integer, maxstock integer, idmarca bigint, precio real, marcastock integer)
RETURNS boolean AS
$BODY$
DECLARE
articulo "Articulo"%ROWTYPE;
BEGIN
SELECT * INTO articulo FROM "Articulo" WHERE "Nombre" = $1 AND "idTipo"=$3 AND "idFamilia"=$4;
IF NOT FOUND THEN
INSERT INTO "Articulo" ("Nombre", "Descripcion", "idTipo", "idFamilia", "Stock", "MinStock", "MaxStock") Values ($1, $2, $3, $4, $5, $6, $7);
SELECT last_value
INTO articulo."idArticulo"
FROM "public"."Articulo_idArticulo_seq";
END IF;
SELECT * …
Run Code Online (Sandbox Code Playgroud) 我有几个工作者,每个工作者都拥有自己与PostgreSQL的连接.工人们操纵着不同的桌子.
工作人员处理来自系统外部的并行请求.正在访问的表之一是用户表.当一些信息出现时,我首先需要确保表中的用户有一条记录.如果没有记录,我希望首先创建一个.
我正在使用以下成语:
if [user does not exist] then [create user]
Run Code Online (Sandbox Code Playgroud)
代码[user does not exist]
是:
SELECT id FROM myschema.users WHERE userId='xyz'
Run Code Online (Sandbox Code Playgroud)
我测试是否返回任何行.
(简化)代码[create user]
是:
INSERT INTO myschema.users VALUES ('xyz')
Run Code Online (Sandbox Code Playgroud)
当我的系统处理有关同一用户的不同信息的并行流时,我经常会收到PostgreSQL错误:
Key (id)=(xyz) already exists
Run Code Online (Sandbox Code Playgroud)
之所以发生这种情况是因为该SELECT
命令不返回任何行,然后另一个工作程序创建用户,任何我的工作程序都尝试执行相同操作,从而导致示例性并发错
根据PostgreSQL文档,默认情况下,每当我隐式启动一个事务时,只要我不提交它,表就会被锁定.我没有使用自动提交,我只在块中提交事务,例如在整个if-else
块之后.
实际上,我可以if-else
直接将这些东西放入SQL中,但它并不能解决我的锁定问题.我假设"赢家全部使用"范例将起作用,并且设法执行SELECT
命令的第一个工作人员将拥有锁,直到它调用COMMIT
.
我在SO上已经阅读了很多不同的主题,但我仍然不确定什么是正确的解决方案.我应该使用显式锁定表,因为隐式锁定不起作用?我怎样才能确保只有一个工人拥有一张桌子?
我正在node.js中编写一个函数来查询PostgreSQL表.
如果该行存在,我想从该行返回id列.
如果它不存在,我想插入它并返回id(insert into ... returning id
).
我一直在尝试变体case
和if else
语句,似乎无法让它发挥作用.
我正在开发一个使用Postgres作为其数据库的Rails 3应用程序.我有下面的表格:
Table "public.test"
Column | Type | Modifiers
---------------+---------+-----------
id | integer | not null
some_other_id | integer |
Indexes:
"test_pkey" PRIMARY KEY, btree (id)
"some_other_id_key" UNIQUE CONSTRAINT, btree (some_other_id)
Run Code Online (Sandbox Code Playgroud)
这有两列:
现在如果我尝试插入一个带有重复的行some_other_id
,它会失败(好)并且我在Postgres日志中得到以下输出:
Run Code Online (Sandbox Code Playgroud)ERROR: duplicate key value violates unique constraint "some_other_id_key"
问题是,我的应用程序尝试添加相同的ID两次是完全主线,并且我的日志被这个"错误"消息垃圾邮件,这会导致各种问题:文件占用大量磁盘空间,诊断会丢失噪音,Postgres必须丢弃diags以保持日志文件的大小限制等.
有谁知道我怎么做:
INSERT
.INSERT
.我听说过规则和触发器,但是我无法工作(虽然我不是Postgres专家).请注意,任何解决方案都需要使用Rails,它执行如下插入:
INSERT INTO test (some_other_id) VALUES (123) RETURNING id;
Run Code Online (Sandbox Code Playgroud) 众所周知,Model.find_or_create_by(X)
实际上:
在步骤1和2之间可能存在争用条件.为了避免数据库中的X重复,应该在X的字段集上使用唯一索引.但是如果应用唯一索引,那么竞争事务之一将失败异常(尝试创建X的副本时).
如何实现"安全版本",#find_or_create_by
它永远不会引发任何异常并始终按预期工作?
postgresql transactions ruby-on-rails upsert rails-activerecord
对于像这样的表:
CREATE TABLE Users(
id SERIAL PRIMARY KEY,
name TEXT UNIQUE
);
Run Code Online (Sandbox Code Playgroud)
以下操作的正确单一查询插入是什么:
给定用户name
,插入新记录并返回新记录id
.但如果name
已经存在,只需返回id
.
我知道PostgreSQL 9.5中的新语法ON CONFLICT(column) DO UPDATE/NOTHING
,但我无法弄清楚,如果有的话,它可以提供帮助,因为我需要id
返回.
这似乎RETURNING id
与ON CONFLICT
不属于一起.
我试图在PostgreSQL 9.2数据库中使用PL/R过程语言.我已经安装了该plr
语言,我正在尝试将其添加到数据库中.当我运行该命令时,CREATE EXTENSION plr;
我收到以下错误:
ERROR: language "C" does not exist
STATEMENT: CREATE EXTENSION plr;
ERROR: language "C" does not exist
Run Code Online (Sandbox Code Playgroud)
当我列出数据库中的可用语言时,select * from pg_language;
我得到了
lanname | lanowner | lanispl | lanpltrusted | lanplcallfoid | laninline | lanvalidator | lanacl
----------+----------+---------+--------------+---------------+-----------+--------------+--------
internal | 10 | f | f | 0 | 0 | 2246 |
c | 10 | f | f | 0 | 0 | 2247 |
sql | 10 | …
Run Code Online (Sandbox Code Playgroud) 我有这个查询,balances
如果表中不存在相应的行,则尝试向表中添加行totals
.使用PostgreSQL上的默认隔离级别在事务中运行查询.
INSERT INTO balances (account_id, currency, amount)
SELECT t.account_id, t.currency, 0
FROM balances AS b
RIGHT OUTER JOIN totals USING (account_id, currency) AS t
WHERE b.id IS NULL
Run Code Online (Sandbox Code Playgroud)
我有一个UNIQUE
约束balances (accountId, currency)
.我担心如果多个会话同时执行此查询,我将陷入竞争状态,导致重复键错误.我已经看过很多关于这个问题的问题,但它们似乎都涉及子查询,多个查询或pgSQL函数.
由于我没有在我的查询中使用任何这些,它是否没有竞争条件?如果不是我该如何解决?
如果我想以递减精度搜索表中的单行,例如:
SELECT * FROM image WHERE name LIKE 'text' AND group_id = 10 LIMIT 1
Run Code Online (Sandbox Code Playgroud)
如果这没有给我结果,请尝试这个:
SELECT * FROM image WHERE name LIKE 'text' LIMIT 1
Run Code Online (Sandbox Code Playgroud)
当这没有给我结果时,尝试这个:
SELECT * FROM image WHERE group_id = 10 LIMIT 1
Run Code Online (Sandbox Code Playgroud)
是否可以只用一种表达方式来做到这一点?
当我没有两个而是例如三个或更多搜索参数时,也会出现问题。有通用的解决方案吗?当然,当搜索结果按相关性排序时,它会派上用场。
我是plpgsql的新手,我正在尝试创建一个函数来检查表中是否存在某个值,如果不存在则会添加一行.
CREATE OR REPLACE FUNCTION hire(
id_pracownika integer,
imie character varying,
nazwisko character varying,
miasto character varying,
pensja real)
RETURNS TEXT AS
$BODY$
DECLARE
wynik TEXT;
sprawdzenie INT;
BEGIN
sprawdzenie = id_pracownika;
IF EXISTS (SELECT id_pracownika FROM pracownicy WHERE id_pracownika=sprawdzenie) THEN
wynik = "JUZ ISTNIEJE";
RETURN wynik;
ELSE
INSERT INTO pracownicy(id_pracownika,imie,nazwisko,miasto,pensja)
VALUES (id_pracownika,imie,nazwisko,miasto,pensja);
wynik = "OK";
RETURN wynik;
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Run Code Online (Sandbox Code Playgroud)
问题是我收到错误,说这id_pracownika
是一个列名和一个变量.
如何在这种上下文中指定"id_pracownika"是指列名?
postgresql ×10
sql ×6
concurrency ×2
plpgsql ×2
sql-insert ×2
upsert ×2
duplicates ×1
function ×1
keyword ×1
locking ×1
node.js ×1
plr ×1
select-into ×1
transactions ×1
union ×1