सही; आइए देखें कि हमारे पास यहां क्या है।
सबसे पहले, कोड को इस प्रकार ब्लॉक करना होगा:
variable declarations
cursor declarations
handler declarations
everything else
तो आपका DECLARE CURSOR c2
चाहिए DECLARE CURSOR c1
. के बीच दिखाई दें और DECLARE CONTINUE HANDLER
. साथ ही, आपको केवल एक CONTINUE HANDLER
. की आवश्यकता है क्योंकि यह घोषणा के बिंदु से प्रक्रिया के अंत तक प्रभावी होता है।
अगला कथन है
INSERT INTO ip_ER_subtotal
SELECT Starting_Pitcher, Game_Date, Game_Number, innings_pitched, 0.0
FROM starting_pitchers_game_log;
SELECT
. में नामित कॉलम क्लॉज वे कॉलम हैं जिन्हें आप से चुन रहे हैं, नहीं जिन्हें आप सम्मिलित कर रहे हैं, इसलिए उन्हें तालिका में कॉलम होना चाहिए starting_pitchers_game_log
. साथ ही, चूंकि कॉलम starting_pitchers_game_log
. से कॉपी नहीं किए जा रहे हैं (अर्थात, ip_total
, er_total
और era
) सभी के डिफ़ॉल्ट मान हैं, आप INSERT
. पर एक कॉलम सूची का उपयोग कर सकते हैं कथन, जैसे:
INSERT INTO pitcher_stats_temp
(Starting_Pitcher, Game_Date, Game_Number, innings_pitched, er)
SELECT pitcher_id, game_date, game_seq, innings_pitched, runs
FROM starting_pitchers_game_log;
यह टाइपिंग, दस्तावेज़ों को सहेजता है कि आप वास्तव में किन कॉलमों में मान डाल रहे हैं और आपके INSERT
को इंसुलेट करता है स्रोत और लक्ष्य तालिका में स्तंभों के भौतिक क्रम से विवरण।
अगला, एक बार जब आप CURSOR c1
. समाप्त कर लेते हैं लूप, टेबल को छोटा न करें या आप अभी-अभी किए गए सभी काम खो देंगे! TRUNCATE TABLE
तालिका में वर्तमान में सभी पंक्तियों को हटा देता है, और पिछले रन के परिणामों को साफ़ करने के लिए यहां उपयोग किया जाता है।
अंत में, दो लूपों में अलग-अलग लेबल होने चाहिए, जैसे fetch_loop_1
और fetch_loop_2
. आपको accum
. को भी रीसेट करना होगा और end_of_cursor
दूसरे लूप में प्रवेश करने से पहले। हालांकि, इस मामले में मेरा मानना है कि हम एक कर्सर के साथ एक लूप में सब कुछ कर सकते हैं, जो कोड को सरल और बनाए रखने में आसान बनाता है।
यह रही पूरी प्रक्रिया:
DROP PROCEDURE IF EXISTS pitcher_stats_era;
DELIMITER $$
CREATE PROCEDURE pitcher_stats_era()
BEGIN
DECLARE pit_id CHAR(10);
DECLARE gdate DATE;
DECLARE seq INT;
DECLARE in_pit REAL;
DECLARE er INT;
DECLARE accum_ip REAL;
DECLARE accum_er INT;
DECLARE earned_run_avg REAL;
DECLARE prev_year YEAR(4);
DECLARE end_of_cursor BOOLEAN;
DECLARE no_table CONDITION FOR SQLSTATE '42S02';
DECLARE c1 CURSOR FOR
SELECT pitcher_id, game_date, game_seq, innings_pitched, earned_runs
FROM pitcher_stats_temp
ORDER BY pitcher_id, game_date, game_seq;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET end_of_cursor := TRUE;
DECLARE EXIT HANDLER FOR no_table
BEGIN
SIGNAL no_table
SET MESSAGE_TEXT = "Work table not initialized. Please call pitcher_stats_reset() before continuing",
MYSQL_ERRNO = 1146;
END;
------------------------------------------------------------------
-- The following steps are now performed by pitcher_stats_reset()
------------------------------------------------------------------
-- TRUNCATE TABLE ip_subtotal; -- Clear our work table for a new run
-- Copy data from main table into work table
-- INSERT INTO ip_subtotal
-- (pitcher_id, game_date, game_seq, innings_pitched, earned_runs)
-- SELECT pitcher_id, game_date, game_seq,
-- IFNULL(innings_pitched, 0), -- replace NULL with 0, if
-- IFNULL(runs, 0) -- column not initialized
-- FROM starting_pitchers_game_log;
---------------------------------------------------------------------
SET end_of_cursor := FALSE; -- reset
SET prev_year := 0; -- reset control-break
OPEN c1;
fetch_loop: LOOP
FETCH c1 INTO pit_id, gdate, seq, in_pit, er;
IF end_of_cursor THEN
LEAVE fetch_loop;
END IF;
-- check control-break conditions
IF YEAR(gdate) != prev_year THEN
SET accum_ip := 0.0;
SET accum_er := 0;
SET prev_year := YEAR(gdate);
END IF;
SET accum_ip := accum_ip + in_pit;
SET accum_er := accum_er + er;
IF accum_er = 0 THEN -- prevent divide-by-zero
SET earned_run_avg := 0;
ELSE
SET earned_run_avg := (accum_ip / accum_er) * 9;
END IF;
UPDATE pitcher_stats_temp
SET ip_total = accum_ip,
er_total = accum_er,
std_era = earned_run_avg
WHERE pitcher_id = pit_id
AND game_date = gdate
AND game_seq = seq;
END LOOP;
CLOSE c1;
END
$$
DELIMITER ;
यही काम करना चाहिए। अगर किसी को कोई बग मिलती है, तो कृपया उसे इंगित करें।
संपादित करें:मैंने स्रोत तालिका से आने वाली नल के खिलाफ सुरक्षा के तरीके और ईआरए गणना पर शून्य से विभाजित होने से बचने के तरीके को स्पष्ट करने के लिए अभी कुछ कोड जोड़ा है।
संपादित करें:मैंने अपने स्वयं के भ्रम को कम करने के लिए अपने मूल कॉलम और टेबल नामों को वापस बदल दिया है।
संपादित करें:मैं एक नई संग्रहीत कार्यविधि का उपयोग करके कार्य तालिका में एक स्तंभ कैसे जोड़ सकता हूं