इसलिए मैं एक स्कीमा स्थापित कर रहा हूं जिसमें मैं एक दूसरे से स्वतंत्र जर्नल प्रविष्टि के लेनदेन इनपुट कर सकता हूं, लेकिन यह भी एक दूसरे पर निर्भर करता है (मुख्य रूप से डेबिट = क्रेडिट सुनिश्चित करने के लिए)। मैंने टेबल, फ़ंक्शन और ट्रिगर सेट अप किया। फिर, जब मैं लेनदेन तालिका में मान इनपुट करने का प्रयास करता हूं, तो मुझे नीचे त्रुटि मिलती है। मैं यह सब pgAdmin4 में कर रहा हूँ।

CREATE TABLE transactions (
    transactions_id UUID PRIMARY KEY DEFAULT uuid_generate_v1(),
    entry_id INTEGER NOT NULL,
    post_date DATE NOT NULL,
    account_id INTEGER NOT NULL,
    contact_id INTEGER NULL,
    description TEXT NOT NULL,
    reference_id UUID NULL,
    document_id UUID NULL,
    amount NUMERIC(12,2) NOT NULL
);

CREATE TABLE entries (
    id UUID PRIMARY KEY,
    test_date DATE NOT NULL,
    balance NUMERIC(12,2)
    CHECK (balance = 0.00)
);

CREATE OR REPLACE FUNCTION transactions_biut()
    RETURNS TRIGGER
    LANGUAGE plpgsql
    AS $$
    BEGIN
        EXECUTE 'INSERT INTO entries (id,test_date,balance)
        SELECT
            entry_id,
            post_date,
            SUM(amount) AS ''balance''
        FROM
            transactions
        GROUP BY
            entry_id;';
    END;
    $$;

CREATE TRIGGER transactions_biut
    BEFORE INSERT OR UPDATE ON transactions
FOR EACH ROW EXECUTE PROCEDURE transactions_biut();
INSERT INTO transactions (
    entry_id,
    post_date,
    account_id,
    description,
    amount
)
VALUES
    (
        '1',
        '2019-10-01',
        '101',
        'MISC DEBIT: PAID FOR FACEBOOK ADS',
        -200.00
    ),
    (
        '1',
        '2019-10-01',
        '505',
        'MISC DEBIT: PAID FOR FACEBOOK ADS',
        200.00
    );

इस इनपुट को निष्पादित करने के बाद, मुझे निम्न त्रुटि मिलती है:

ERROR:  column "id" of relation "entries" does not exist
LINE 1: INSERT INTO entries (id,test_date,balance)
                             ^
QUERY:  INSERT INTO entries (id,test_date,balance)
        SELECT
            entry_id,
            post_date,
            SUM(amount) AS "balance"
        FROM
            transactions
        GROUP BY
            entry_id;
CONTEXT:  PL/pgSQL function transactions_biut() line 2 at EXECUTE
SQL state: 42703
0
James Agius 12 अक्टूबर 2019, 00:05
मैं पुन: पेश नहीं कर सकता। मुझे जो सिंटैक्स त्रुटि मिलती है वह लगभग balance है।
 – 
Bergi
12 अक्टूबर 2019, 01:11
बीटीडब्ल्यू, स्ट्रिंग क्वेरी के साथ EXECUTE का उपयोग करने की कोई आवश्यकता नहीं है। बस INSERT को plsql स्टेटमेंट के रूप में करें।
 – 
Bergi
12 अक्टूबर 2019, 01:14
इनपुट के लिए धन्यवाद, अभी भी इसके चारों ओर अपना रास्ता सीख रहा हूं।
 – 
James Agius
12 अक्टूबर 2019, 03:07

2 जवाब

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

यहां कुछ समस्याएं हैं:

  • आप ट्रिगर फ़ंक्शन से कुछ भी वापस नहीं कर रहे हैं => शायद return NEW या return OLD होना चाहिए क्योंकि आप कुछ भी संशोधित नहीं कर रहे हैं
  • चूंकि आप प्रत्येक पंक्ति से पहले ट्रिगर निष्पादित कर रहे हैं, यह किसी भी लेन-देन के लिए विफल होने के लिए बाध्य है जो 0 => नहीं है शायद आप एक स्थगित constraint trigger चाहते हैं?
  • आप post_date के आधार पर समूह नहीं बना रहे हैं, इसलिए आपका चयन विफल होना चाहिए
  • आपने entry_id को INTEGER के रूप में परिभाषित किया है, लेकिन entries.id UUID प्रकार का है

यह भी ध्यान दें कि यह वास्तव में बड़े पैमाने पर नहीं जा रहा है (आप सभी दिनों के सभी लेन-देन को जोड़ रहे हैं, इसलिए यह धीमा और धीमा हो जाएगा ...)

1
Chris 12 अक्टूबर 2019, 01:10
धन्यवाद क्रिस। मैं वास्तव में एक मित्र के साथ परामर्श कर रहा था कि ट्रिगर को केवल उन लेन-देन तक कैसे सीमित किया जाए जिन्हें मैं वर्तमान में इनपुट करने का प्रयास कर रहा हूं। आपके दूसरे बिंदु के लिए, क्या प्रत्येक पंक्ति के बजाय पूरे कथन पर इसे लागू करने का कोई तरीका है?
 – 
James Agius
12 अक्टूबर 2019, 03:25
इस प्रश्न पर एक नज़र डालें: स्थगित बाधाओं के लिए stackoverflow.com/q/16323236/7159043
 – 
Chris
12 अक्टूबर 2019, 09:42
आम तौर पर, आप अपने मॉडल पर पुनर्विचार करना चाह सकते हैं, उदा। लेन-देन "समूह" के साथ एक मध्यवर्ती तालिका जोड़ें, जिसे आप अपनी लेन-देन तालिका में "स्थानांतरित" करते हैं, यदि वे 0 तक जोड़ते हैं।
 – 
Chris
12 अक्टूबर 2019, 09:45

@chirs मैं यह पता लगाने में सक्षम था कि कथन-स्तरीय ट्रिगर्स का उपयोग करके एक कार्यशील समाधान कैसे बनाया जाए:

CREATE TABLE transactions (
    transactions_id UUID PRIMARY KEY DEFAULT uuid_generate_v1(),
    entry_id INTEGER NOT NULL,
    post_date DATE NOT NULL,
    account_id INTEGER NOT NULL,
    contact_id INTEGER NULL,
    description TEXT NOT NULL,
    reference_id UUID NULL,
    document_id UUID NULL,
    amount NUMERIC(12,2) NOT NULL
);

CREATE TABLE entries (
    entry_id INTEGER PRIMARY KEY,
    post_date DATE NOT NULL,
    balance NUMERIC(12,2),
    CHECK (balance = 0.00)
);

CREATE OR REPLACE FUNCTION transactions_entries() RETURNS TRIGGER AS $$
    BEGIN
        IF (TG_OP = 'DELETE') THEN
            INSERT INTO entries
                SELECT o.entry_id, o.post_date, SUM(o.amount) FROM old_table o GROUP BY o.entry_id, o.post_date;
        ELSIF (TG_OP = 'UPDATE') THEN
            INSERT INTO entries
                SELECT o.entry_id, n.post_date, SUM(n.amount) FROM new_table n, old_table o GROUP BY o.entry_id, n.post_date;
        ELSIF (TG_OP = 'INSERT') THEN
            INSERT INTO entries
                SELECT n.entry_id,n.post_date, SUM(n.amount) FROM new_table n GROUP BY n.entry_id, n.post_date;
        END IF;

        RETURN NULL; -- result is ignored since this is an AFTER trigger
    END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER transactions_ins
    AFTER INSERT ON transactions
    REFERENCING NEW TABLE AS new_table
    FOR EACH STATEMENT EXECUTE PROCEDURE transactions_entries();
CREATE TRIGGER transactions_upd
    AFTER UPDATE ON transactions
    REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table
    FOR EACH STATEMENT EXECUTE PROCEDURE transactions_entries();
CREATE TRIGGER transactions_del
    AFTER DELETE ON transactions
    REFERENCING OLD TABLE AS old_table
    FOR EACH STATEMENT EXECUTE PROCEDURE transactions_entries();

अनुकूलन पर कोई विचार?

0
James Agius 14 अक्टूबर 2019, 20:42
क्या आप वाकई अपडेट पर नई और पुरानी पंक्तियों के बीच कार्टेशियन जॉइन करना चाहते हैं? यह मुझे अजीब लगता है। साथ ही, transactions में डिलीट करने पर, आप entries के अनुसार पंक्तियों को डुप्लिकेट करते हैं - क्यों? यदि मूल "प्रविष्टि" में उदा. 4 "लेन-देन" और उनमें से केवल दो हटा दिए गए हैं (यह मानते हुए कि दो प्रत्येक को 0 तक जोड़ते हैं)?
 – 
Chris
14 अक्टूबर 2019, 22:26
मुझे लगता है कि क्या होता है यह देखने के लिए कुछ सामान्य मामलों के साथ परीक्षण करना एक बात है और यदि यह आप जो खोज रहे हैं उससे मेल खाता है।
 – 
Chris
14 अक्टूबर 2019, 22:27
हम्म, यह विचार के लिए भोजन है। मैं इसकी जांच करूंगा और विभिन्न जटिल प्रविष्टियों को चलाना शुरू करूंगा और देखूंगा कि क्या होता है। धन्यवाद क्रिस!
 – 
James Agius
16 अक्टूबर 2019, 16:23