तो एसओ पर मेरा पहला प्रश्न, मुझे सेटअप का वर्णन करने दें: मेरे पास एक टेबल गिल्ड के साथ एक पोस्टग्रेसक्ल डेटाबेस (संस्करण 12) है (जिसमें एक आंतरिक गिल्ड_आईडी और कुछ अन्य सूचनाएं हैं)। guild_id का उपयोग कई अन्य तालिकाओं जैसे टीम तालिका के लिए विदेशी कुंजी के रूप में किया जाता है। अब यदि एक टीम किसी अन्य गिल्ड के लिए टीमों में डाली जाती है तो गिल्ड_आईडी = 1 के साथ गिल्ड, मैं एक ही टीम प्रविष्टि बनाने के लिए एक ट्रिगर फ़ंक्शन चाहता हूं, लेकिन अब एक संशोधित गिल्ड_आईडी के साथ (अब 1 होना चाहिए)।

प्रासंगिक चीजों की परिभाषा जो मेरे पास एटीएम है:

create table if not exists bot.guilds
(
    guild_id         bigserial not null
        constraint guilds_pk
            primary key,
    guild_dc_id      bigint    not null,
);
create table if not exists bot.teams
(
    team_id       bigserial   not null
        constraint teams_pk
            primary key,
    guild_id      bigserial      not null
        constraint teams_guilds_guild_id_fk
            references bot.guilds
            on delete cascade,
    team_name     varchar(20) not null,
    team_nickname varchar(10) not null
);

alter table bot.teams
    owner to postgres;

create unique index if not exists teams_guild_id_team_name_uindex
    on bot.teams (guild_id, team_name);

create unique index if not exists teams_guild_id_team_nickname_uindex
    on bot.teams (guild_id, team_nickname);

create function duplicate_teams() returns trigger
    language plpgsql
as
$$
BEGIN
    INSERT INTO bot.teams VALUES(1,NEW."team_name",NEW."team_nickname");
RETURN NEW;
END;
$$;

create trigger duplicate_team
    after insert
    on bot.teams
    for each row
execute procedure bot.duplicate_teams();

अगर मैं टीमों (INSERT INTO bot.teams ("guild_id", "team_name", "team_nickname")VALUES (14, 'test2', 'test2');) में एक नई पंक्ति डालने का प्रयास करता हूं, तो मुझे निम्न त्रुटि संदेश मिलता है (मूल जर्मन, मेरे द्वारा अंग्रेजी में अनुवादित):

[42804] ERROR: Column »guild_id« has type integer, but the expression has the type character varying
HINT: You have to rewrite the expression or cast the value.
WITH: PL/pgSQL-function duplicate_teams() row 3 in SQL-expressions

निष्पादन के बाद ओरिजिनल इंसर्ट स्टेटमेंट न तो टेबल में है और न ही कॉपी। मैंने गिल्ड आईडी के लिए सीरियल, पूर्णांक, बड़े सीरियल के लिए मान डालने की कोशिश की .. लेकिन हर बार एक ही त्रुटि। मैं त्रुटि संदेश भाग से उलझन में हूं "इसमें टाइप कैरेक्टर अलग-अलग है"।

तो मेरे प्रश्न हैं:

  1. क्या मेरी समझ सही है, कि त्रुटि ट्रिगर के कारण होती है? और ट्रिगर में त्रुटि के कारण मूल सम्मिलन कथन भी काम नहीं करता है?
  2. कलाकारों के साथ भी प्रकार भिन्न क्यों है?
  3. कोड में त्रुटि कहां है?

मैंने समस्या की खोज करने की कोशिश की, लेकिन कुछ भी मददगार नहीं मिला। किसी भी संकेत का स्वागत है। आपके सहयोग के लिए धन्यवाद!

संपादित करें: @ लुकास थेलर का जवाब काम करता है, लेकिन अब मुझे एक नई त्रुटि मिलती है:

[23505] ERROR: doubled key value violates unique-constraint »teams_guild_id_team_name_uindex«
Detail: Key»(guild_id, team_name)=(1, test3)« exists already.
WHERE: SQL-Statement»INSERT INTO bot.teams(guild_id, team_name, team_nickname)  VALUES(1,NEW."team_name",NEW."team_nickname")«
PL/pgSQL-Function duplicate_teams() row 3 in SQL-Statement
SQL-Statment »INSERT INTO bot.teams(guild_id, team_name, team_nickname)  VALUES(1,NEW."team_name",NEW."team_nickname")«
PL/pgSQL-Function duplicate_teams() row 3 in SQL-Statement

लेकिन तालिका में केवल "3,11, TeamUtils, TU" है...

2
Doluk 17 मार्च 2021, 12:39
नोट: a) धारावाहिक ऐसा न करें में हैं, b ) क्या आप INSERT INTO bot.teams AFTER INSERT ON bot.teams का प्रयास कर रहे हैं?
 – 
Alex Yu
17 मार्च 2021, 13:26
अपने संपादन के संदर्भ में: क्या आप select currval('bot.teams_guild_id_seq') करने का प्रयास कर सकते हैं? जैसा कि @AlexYu ने उल्लेख किया है, SERIALS कई बार अजीब हो सकता है। इस तथ्य को देखते हुए कि यह एक विदेशी कुंजी है, आप शायद bot.teams.guild_id को BIGINT में परिवर्तित करने से बेहतर हैं, वैसे भी (मुझे नहीं लगता कि ऑटो-इन्क्रीमेंटिंग चाइल्ड टेबल में इच्छित व्यवहार है)
 – 
Lukas Thaler
17 मार्च 2021, 13:37

1 उत्तर

सबसे बढ़िया उत्तर

bot.teams में चार कॉलम हैं: team_id, guild_id (दोनों संख्यात्मक डेटा प्रकार), team_name और team_nickname (दोनों वर्चर)। फ़ंक्शन परिभाषा में आपके INSERT कथन में, आप केवल तीन मान प्रदान करते हैं और विशेष कॉलम से कोई संबंध नहीं है। डिफ़ॉल्ट उन्हें क्रम में सम्मिलित करना है, जो 1 से team_id और (महत्वपूर्ण) NEW."team_name" से guild_id असाइन करता है, इसलिए इंसर्ट एक प्रकार की बेमेल त्रुटि के साथ विफल हो जाता है।

निर्दिष्ट करना

INSERT INTO bot.teams(guild_id, team_name, team_nickname)  VALUES(1,NEW."team_name",NEW."team_nickname");

आपके कार्य में आपकी समस्या का समाधान करना चाहिए


अपने अन्य प्रश्नों का उत्तर देने के लिए:

  1. INSERT स्टेटमेंट को लेन-देन के अंदर निष्पादित किया जा रहा है, और ट्रिगर में एक विफलता के कारण पूरे लेन-देन को निरस्त कर दिया जाएगा और वापस ले लिया जाएगा, इसलिए आपको तालिका में डाली गई मूल पंक्ति दिखाई नहीं देगी, या तो
  2. प्रकार कास्ट से विचलित नहीं हो रहा है, यह गलत मान डाला जा रहा था जिससे डेटा प्रकार बेमेल हो गया
0
Lukas Thaler 17 मार्च 2021, 13:24
ओह डैम, मैं बेवकूफ हूँ। अब एक और त्रुटि दिखाई देती है :)। अब तक आपकी मदद के लिए धन्यवाद!
 – 
Doluk
17 मार्च 2021, 13:09
क्या आप कृपया बता सकते हैं कि guild_id को 1 क्यों पास किया जाता है? यह मेरे लिए अजीब लग रहा है। क्या यह किसी प्रकार का serial व्यवहार है?
 – 
Alex Yu
19 मार्च 2021, 10:56
1 (अन्य सभी सम्मिलित मूल्यों की तरह) उनके पोस्ट में ओपी फ़ंक्शन परिभाषा से लिया गया है। मुझे नहीं पता कि उनका इरादा क्या है, वहाँ
 – 
Lukas Thaler
19 मार्च 2021, 10:59