我无法访问NEW
查询字符串中crosstab()
行的值。
CREATE OR REPLACE FUNCTION insert_fx()
RETURNS TRIGGER AS
$BODY$
BEGIN
INSERT INTO outputtb (serial,date, judge)
VALUES (NEW.serial, NEW.date, NEW.tjudge) RETURNING serial INTO newserial;
UPDATE outputtb
SET (reading1,
reading2,
reading3) =
(SELECT ct."reading1",
ct."reading2",
ct."reading3"
FROM crosstab( $$
SELECT tb2. serial,tb2. readings,tb2. value
FROM DATA AS tb2
INNER JOIN outputtb AS tb1 USING (serial)
WHERE tb2.serial = $$||NEW.serno||$$
ORDER BY 1 ASC $$, $$
VALUES ('reading1'),('reading2'),('reading3')$$
) ct ("Serial" VARCHAR(50),"Reading1" FLOAT8, "Reading2" FLOAT8, "Reading3" FLOAT8))
WHERE sn = NEW.serno;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER insert_tg
BEFORE INSERT ON details
FOR EACH ROW EXECUTE PROCEDURE insert_fx();
它返回此错误:
ERROR: syntax error at or near "CC1027HCA0GESKN00CC000FT0000" LINE 6: tb2. serial = 043611007853619CC1027HCA0GESKN00CC000FT...
我认为它不接受字符,它只接受整数。也许引用需要一些修改,我不熟悉pgsql引用。
我需要帮助来完成我的项目。我坚持这一部分。
答案 0 :(得分:2)
错误消息的直接原因是您在没有引用的情况下连接字符串NEW.serno
。要安全地修复使用format()
or quote_literal()
or quote_nullable()
。
...
UPDATE outputtb
SET (reading1, reading2, reading3)
= (SELECT ct.reading1, ct.reading2, ct.reading3
FROM crosstab(
'SELECT serial, t2.readings, t2.value
FROM data t2
JOIN outputtb t1 USING (serial)
WHERE serial = ' || quote_nullable(NEW.serno) || '
ORDER BY 1'
, $$VALUES ('reading1'),('reading2'),('reading3')$$
) ct (serial text, reading1 float8, reading2 float8, reading3 float8))
WHERE sn = NEW.serno;
...
基础:
顺便说一句,我还修复了不正确的混合大小写标识符:
但还有更多问题:
newserial
尚未宣布,也未被使用。outputtb
在传递给crosstab()
的查询中是无意义的噪音。INSERT
和 UPDATE
,crosstab()
似乎也有点矫枉过正。< / LI>
这是一个很大的混乱。
走出困境,我受过教育的猜测是你想要这个:
CREATE OR REPLACE FUNCTION insert_fx()
RETURNS TRIGGER AS
$func$
BEGIN
INSERT INTO outputtb (serial, date, judge, reading1, reading2, reading3)
SELECT NEW.serial, NEW.date, NEW.tjudge, ct.*
FROM (SELECT 1) dummy
LEFT JOIN crosstab (
'SELECT serial, readings, value
FROM data
WHERE serial = ' || quote_nullable(NEW.serno) || '
ORDER BY 1'
, $$VALUES ('reading1'),('reading2'),('reading3')$$
) ct (serial text, reading1 float8, reading2 float8, reading3 float8) ON true;
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
LEFT JOIN
到dummy
表可防止在INSERT
出现空白时失去crosstab()
。
可以简化为:
CREATE OR REPLACE FUNCTION insert_fx()
RETURNS TRIGGER AS
$func$
BEGIN
INSERT INTO outputtb (serial, date, judge, reading1, reading2, reading3)
SELECT NEW.serial, NEW.date, NEW.tjudge
min(value) FILTER (WHERE readings = 'reading1')
min(value) FILTER (WHERE readings = 'reading2')
min(value) FILTER (WHERE readings = 'reading3')
FROM data
WHERE serial = NEW.serno;
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
由于我们现在汇总,结果排是有保证的,我们不必防止丢失它。
除了: &#34;串行&#34;是not a reserved word。但它是常见伪数据类型的名称,因此我仍然不会将其用作列名,以避免混淆错误情况。
答案 1 :(得分:0)
这条线对我不起作用。
serial = ' || quote_nullable(NEW.serno) || '
它会返回此错误。
缺少表格“new”的子句条目。
相反,我使用它。
serial = $$||quote_literal(NEW.serno)||$$