我编写了一个查询记录存在的查询,如果条件为真,则会更新,否则会插入新记录。
问题是插入时,它返回Query returned successfully: 1 rows affected, 200ms execution time.
但更新时返回"查询成功返回:0行受影响,190毫秒执行时间。"但值正确更新。
这是创建表的示例脚本
CREATE TABLE sample
(
templateid integer NOT NULL DEFAULT nextval('checktemplate_language_lookup_seq'::regclass),
languageid integer NOT NULL,
templatetitle character varying(100),
disclaimer text,
createdby integer NOT NULL,
createdtimestamp timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp without time zone,
updatedby integer,
updatedtimestamp timestamp without time zone,
CONSTRAINT sample_templateid_languageid UNIQUE (templateid, languageid)
)
在表格中插入新记录:
WITH new_values (templateId, languageId, templatetitle, disclaimer, createdby,createdtimestamp,updatedby,updatedtimestamp)
AS (
VALUES (1, 1, 'LangTemplateTitle1', 'LangDisclaimer1', 1,current_timestamp,1,current_timestamp)
), upsert
AS (
UPDATE sample m
SET templatetitle = nv.templatetitle, disclaimer = nv.disclaimer, updatedby = nv.updatedby, updatedTimeStamp = nv.updatedtimestamp
FROM new_values nv
WHERE m.templateId = nv.templateId AND m.languageId = nv.languageId RETURNING m.*
)
INSERT INTO sample (templateId, languageId, templatetitle, disclaimer, createdby,createdtimestamp)
SELECT templateId, languageId, templatetitle, disclaimer, createdby ,createdtimestamp
FROM new_values
WHERE NOT EXISTS (
SELECT 1
FROM upsert up
WHERE up.templateId = new_values.templateId AND up.languageId = new_values.languageId
)
使用不同的值更新同一行:(更新相同的查询值)
WITH new_values (templateId, languageId, templatetitle, disclaimer, createdby,createdtimestamp,updatedby,updatedtimestamp)
AS (
VALUES (1, 1, 'LangTemplateTitle2', 'LangDisclaimer2', 1,current_timestamp,1,current_timestamp)
), upsert
AS (
UPDATE sample m
SET templatetitle = nv.templatetitle, disclaimer = nv.disclaimer, updatedby = nv.updatedby, updatedTimeStamp = nv.updatedtimestamp
FROM new_values nv
WHERE m.templateId = nv.templateId AND m.languageId = nv.languageId RETURNING m.*
)
INSERT INTO sample (templateId, languageId, templatetitle, disclaimer, createdby,createdtimestamp)
SELECT templateId, languageId, templatetitle, disclaimer, createdby ,createdtimestamp
FROM new_values
WHERE NOT EXISTS (
SELECT 1
FROM upsert up
WHERE up.templateId = new_values.templateId AND up.languageId = new_values.languageId
)
我如何得到"没有行影响价值"即使我使用相同的查询进行更新
答案 0 :(得分:0)
默认PG行为是仅返回与最终语句相关的消息,在这种情况下始终是INSERT
语句,即使UPDATE
实际完成了工作,{{1语句什么都不做。如果要自定义消息,则必须将此语句转换为PL / pgSQL函数,您可以INSERT
使用自己设计的消息。
也就是说,如果你使用 PG 9.5 + ,你可以使用RAISE NOTICE
的{{1}}子句来获得更清晰的声明:
ON CONFLICT
请注意最后两个INSERT
分配:指定引用和插入时间,但是当更新发生时,这些值将成为更新引用和时间。 INSERT INTO sample (templateId, languageId, templatetitle, disclaimer, createdby, createdtimestamp)
VALUES (1, 1, 'LangTemplateTitle1', 'LangDisclaimer1', 1,current_timestamp)
ON CONFLICT (templateId, languageId) DO UPDATE
SET templatetitle = EXCLUDED.templatetitle, disclaimer = EXCLUDED.disclaimer,
updatedby = EXCLUDED.createdby, updatedTimeStamp = EXCLUDED.createdtimestamp;
引用其值导致冲突的行,在本例中是SET
子句中的值。
即使您使用的是 PG9.4 ,也可以使用EXCLUDED
信息而不是代价高昂的VALUES
改进查询:
RETURNING *
这利用了如果WHERE EXISTS
没有发生,WITH nv (templateId, languageId, templatetitle, disclaimer, opBy, opTimestamp) AS (
VALUES (1, 1, 'LangTemplateTitle2', 'LangDisclaimer2', 1, current_timestamp)
), upsert AS (
UPDATE sample m
SET templatetitle = nv.templatetitle, disclaimer = nv.disclaimer, updatedby = nv.opBy, updatedTimeStamp = nv.opTimestamp
FROM nv
WHERE m.templateId = nv.templateId AND m.languageId = nv.languageId
RETURNING m.*
)
INSERT INTO sample (templateId, languageId, templatetitle, disclaimer, createdby, createdtimestamp)
SELECT nv.templateId, nv.languageId, nv.templatetitle, nv.disclaimer, nv.opBy, nv.opTimestamp
FROM nv, upsert
WHERE upsert.templateId IS NULL;
返回所有空值的事实。另请注意使用UPDATE
和RETURNING *
来进一步简化语句。