前一个触发器完全完成后在触发器中执行 TRUNCATE

问题描述 投票:0回答:1

我在尝试在第一个触发器完全完成后执行第二个触发器时遇到问题。第一个触发器基于表上的 AFTER INSERT 执行。我只想在第一个触发器之后运行第二个触发器,因为第二个触发器只是一个截断语句,从之前插入新行的表中删除数据。

这是代码和错误:

CREATE OR REPLACE FUNCTION public.new_vppasubmission_trigger_function()
    RETURNS trigger AS
$$
BEGIN

INSERT INTO contact("contact_id", "submission_date", "first_name", "last_name", "street_address", "street_address_2", "city", "state",
                    "zip", "county", "phone_number", "email", "dob", "facebook_exists", "facebook_year", "facebook_email", 
                    "facebook_phone_number")
SELECT "contact_id", "submission_date", "first_name", "last_name", "street_address", "street_address_2", "city", "state",
        "zip", "county", "phone_number", "email", "dob", "facebook_exists", "facebook_year", "facebook_email", "facebook_phone_number"
FROM "VPPA_HOLDING"
ON CONFLICT("email") DO UPDATE SET "submission_date" = EXCLUDED.submission_date, "first_name" = EXCLUDED.first_name,
                                "last_name" = EXCLUDED.last_name, "street_address" = EXCLUDED.street_address, "street_address_2" = EXCLUDED.street_address_2,
                                "city" = EXCLUDED.city, "state" = EXCLUDED.state, "zip" = EXCLUDED.zip, "county" = EXCLUDED.county, "phone_number" = EXCLUDED.phone_number,
                                "dob" = EXCLUDED.dob, "facebook_exists" = EXCLUDED.facebook_exists, "facebook_year" = EXCLUDED.facebook_year, 
                                "facebook_email" = EXCLUDED.facebook_email, "facebook_phone_number" = EXCLUDED.facebook_phone_number;

INSERT INTO "SPLIT_FROM_VPPA_HOLDING"("contact_id", "submission_date", "service", "first_name", "last_name", "street_address",
                                        "street_address_2", "city", "state", "zip", "county", "phone_number", "email", "dob", "facebook_exists", "facebook_year",
                                        "facebook_email", "facebook_phone_number", "submission_id", "investigating_claims", "discovery_package", "discovery_email",
                                        "disney_package", "disney_email", "espn_package", "espn_email", "fubo_package", "fubo_email", "hbo_package", "hbo_email",
                                        "hulu_package", "hulu_email", "mgm_package", "mgm_email", "paramount_package", "paramount_email", "peacock_package",
                                        "peacock_email", "showtime_package", "showtime_email", "sling_package", "sling_email",
                                        "starz_package", "starz_email", "amc_package", "amc_email")
SELECT "contact_id", "submission_date", trim(unnest(string_to_array("services", ';'))), "first_name", "last_name", "street_address",
        "street_address_2", "city", "state", "zip", "county", "phone_number", "email", "dob", "facebook_exists", "facebook_year",
        "facebook_email", "facebook_phone_number", "submission_id", "investigating_claims", "discovery_package", "discovery_email",
        "disney_package", "disney_email", "espn_package", "espn_email", "fubo_package", "fubo_email", "hbo_package", "hbo_email",
        "hulu_package", "hulu_email", "mgm_package", "mgm_email", "paramount_package", "paramount_email", "peacock_package",
        "peacock_email", "showtime_package", "showtime_email", "sling_package", "sling_email",
        "starz_package", "starz_email", "amc_package", "amc_email"
FROM "VPPA_HOLDING";

INSERT INTO "VPPA_AMC"
SELECT "contact_id", "amc_package", "amc_email","submission_date"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'AMC+';

INSERT INTO "VPPA_DISCOVERY"
SELECT "contact_id", "discovery_package", "discovery_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'Discovery+';

INSERT INTO "VPPA_DISNEY"
SELECT "contact_id", "disney_package", "disney_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'Disney+';

INSERT INTO "VPPA_ESPN"
SELECT "contact_id", "espn_package", "espn_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'ESPN+';

INSERT INTO "VPPA_FUBO"
SELECT "contact_id", "fubo_package", "fubo_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'Fubo';

INSERT INTO "VPPA_HBO"
SELECT "contact_id", "hbo_package", "hbo_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'HBO MAX';

INSERT INTO "VPPA_HULU"
SELECT "contact_id", "hulu_package", "hulu_email", "submission_date", "email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'Hulu';
--ON CONFLICT("primary_email") DO UPDATE SET "package" = EXCLUDED.package, "submission_date" = EXCLUDED.submission_date, "streaming_email" = EXCLUDED.hulu_email;

INSERT INTO "VPPA_MGM"
SELECT "contact_id", "mgm_package", "mgm_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'MGM+';

INSERT INTO "VPPA_PARAMOUNT"
SELECT "contact_id", "paramount_package", "paramount_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'Paramount+';

INSERT INTO "VPPA_PEACOCK"
SELECT "contact_id", "peacock_package", "peacock_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'Peacock';

INSERT INTO "VPPA_SHOWTIME"
SELECT "contact_id", "showtime_package", "showtime_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'Showtime Anytime';

INSERT INTO "VPPA_SLING"
SELECT "contact_id", "sling_package", "sling_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'Sling';

INSERT INTO "VPPA_STARZ"
SELECT "contact_id", "starz_package", "starz_email"
FROM "SPLIT_FROM_VPPA_HOLDING"
WHERE "service" = 'Starz';

RETURN NEW;

END;
$$
LANGUAGE 'plpgsql';

CREATE TRIGGER new_vppasubmission_trigger
  AFTER INSERT
  ON "VPPA_HOLDING"
  FOR EACH ROW
  EXECUTE PROCEDURE new_vppasubmission_trigger_function();
CREATE OR REPLACE FUNCTION public.new_vppasubmission_trigger_function2()
    RETURNS trigger AS
$$
BEGIN
TRUNCATE TABLE "SPLIT_FROM_VPPA_HOLDING", "VPPA_HOLDING";

RETURN NEW;
 
END;
$$
LANGUAGE 'plpgsql';

CREATE TRIGGER new_vppasubmission_trigger2
  AFTER INSERT
  ON "VPPA_HOLDING"
  FOR EACH ROW
  EXECUTE PROCEDURE new_vppasubmission_trigger_function2();

尝试过,但收到错误消息,指出它无法截断,因为它正在被此会话中的活动查询使用。

sql postgresql triggers
1个回答
0
投票

您的代码有很多方面需要注意。但核心问题是:

您不能在由同一表触发的触发器中

TRUNCATE
表(在您的示例中为
"VPPA_HOLDING"
)。这是不可能的,并且会引发您观察到的错误。

错误:无法截断“VPPA_HOLDING”,因为此会话中的活动查询正在使用它

(您应该一开始就逐字报告错误消息。不是散文,而是准确引用。)

您可以将

TRUNCATE
替换为无条件
DELETE FROM "VPPA_HOLDING"M;
以消除错误。无论如何,对于少量的行来说,这会更快。 (只需确保在许多
DELETE
堆积死元组之前清理表即可。)

但整个方法一开始看起来效率很低。考虑...

  • 单个触发功能而不是两个。
  • 具有多个数据修改 CTE 的单个命令可替换许多单独的
    INSERT
    命令
  • 或者(更好)一个关系模型,没有为每个其他公司提供单独的表。
  • 临时表作为垫脚石。对于易失性数据来说,这些要便宜得多。
  • 所有持久化
    INSERT
    语句的目标列列表。
  • 没有这种奇怪的大小写标识符混合的命名策略。
© www.soinside.com 2019 - 2024. All rights reserved.