加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

plpgsql语法错误在“;”附近

发布时间:2020-12-14 05:44:25 所属栏目:Windows 来源:网络整理
导读:我已经查看了 this个类似问题,但我认为我的问题可能有所不同.如果我正确理解他们的问题,问题是由上游的语法错误引起的. 在我的情况下,语法错误是如此接近程序的开头,它给了我一个可能出错的窗口,但是一切看起来都没问题. 码: DO $$DECLARE topic_cursor CUR
我已经查看了 this个类似问题,但我认为我的问题可能有所不同.如果我正确理解他们的问题,问题是由上游的语法错误引起的.
在我的情况下,语法错误是如此接近程序的开头,它给了我一个可能出错的窗口,但是一切看起来都没问题.

码:

DO $$
DECLARE topic_cursor CURSOR FOR SELECT * FROM "socialMediaModel_topic" WHERE "active_search"=True;

BEGIN
OPEN topic_cursor;
FETCH FIRST FROM topic_cursor;
LOOP
    SELECT "topic" FROM topic_cursor AS "c_topic";
    SELECT "topic_id" FROM topic_cursor AS "c_id";
    SELECT "active_search" FROM topic_cursor AS "c_active";

    INSERT INTO "socialMediaModel_datacollection" ("name","active")
        VALUES (c_topic,c_active);
    INSERT INTO "socialMediaModel_datacollectiontopic" ("data_collection_id_id","topic_id_id")
        VALUES ((SELECT "data_collection_id" FROM "DataCollection" where name=c_topic),c_id);

    FETCH NEXT FROM topic_cursor;

END LOOP;
CLOSE topic_cursor;

UPDATE "socialMediaModel_topic" SET "active_search" = False WHERE "active_search"=True;
COMMIT;
END$$;

错误:

ERROR:  syntax error at or near ";"
LINE 9:  FETCH FIRST FROM topic_cursor;
                                  ^
********** Error **********

ERROR: syntax error at or near ";"
SQL state: 42601
Character: 247

在编写此脚本时,我几乎完全遵循这些资源:

> PostgreSQL Documentation: Cursors
> PostgreSQL Documentation: DO

数据库:PostgreSQL 9.1
编辑:pgAdmin III查询工具

如果我错过了一些非常明显的事情,我会提前道歉.我一整天都在盯着这个剧本,所以我的大脑可能会有点乱.

解决方法

程序解决方案

您的代码中存在许多问题.
这应该工作,也更快:

DO
$do$
DECLARE
   rec record;
BEGIN
   FOR rec IN
      SELECT s.*,d.data_collection_id
      FROM   "socialMediaModel_topic" s
      LEFT   JOIN "DataCollection"    d ON d.name = s.topic
      WHERE  active_search
   LOOP
      INSERT INTO "socialMediaModel_datacollection" (name,active)
      VALUES (rec.topic,rec.active_search);
      INSERT INTO "socialMediaModel_datacollectiontopic"
                              (data_collection_id_id,topic_id_id)
      VALUES (rec.data_collection_id,rec.topic_id);
   END LOOP;

   UPDATE "socialMediaModel_topic"
   SET    active_search = FALSE
   WHERE  active_search;
END
$do$;

主要观点

> FETCH syntax不正确.
> DO语句中没有COMMIT.整个事情在一个事务中自动运行,就像一个函数.
>你没有条件终止你的循环.
>几乎没有必要使用显式游标.使用FOR loop的更方便(通常更快)的隐式游标.
>我会建议反对Postgres中的CaMeL案例标识符.仅使用合法的小写标识符.

基于集合的解决方案

整个程序方法不如data-modifying CTEs的基于集合的方法:

WITH ins1 AS (
   INSERT INTO "socialMediaModel_datacollection" (name,active)
   SELECT topic,active_search
   FROM   "socialMediaModel_topic"
   WHERE  active_search
   ),ins2 AS (
   INSERT INTO "socialMediaModel_datacollectiontopic"
                           (data_collection_id_id,topic_id_id)
   SELECT d.data_collection_id,s.topic_id
   FROM   "socialMediaModel_topic" s
   LEFT   JOIN "DataCollection"    d ON d.name = s.topic
   WHERE  s.active_search
   )
UPDATE "socialMediaModel_topic"
SET    active_search = FALSE
WHERE  active_search;

或者,如果您有并发写入加载,请使用FOR UPDATE以避免竞争条件:

WITH sel AS (
   SELECT s.topic_id,s.topic,s.active_search,d.data_collection_id
   FROM   "socialMediaModel_topic" s
   LEFT   JOIN "DataCollection"    d ON d.name = s.topic
   WHERE  s.active_search
   FOR    UPDATE
   ),ins1 AS (
   INSERT INTO "socialMediaModel_datacollection" (name,active_search FROM sel
   ),s.topic_id FROM sel
   )
UPDATE "socialMediaModel_topic"
SET    active_search = FALSE
WHERE  active_search;

更多关于SELECT … FOR CTD更新:
Should I include SELECTs in a transaction?

类似的问题/答案:
How to improve performance of a function with cursors in PostgreSQL?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读