Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bagaimana saya bisa menambahkan kolom ke tabel kerja menggunakan prosedur tersimpan baru

Pertanyaan ini, dan jawabannya, dibangun di atas jawaban untuk Bagaimana cara menggabungkan dua prosedur dalam satu untuk mengisi satu tabel daripada masing-masing dari dua prosedur yang mengisi tabelnya sendiri? dan Bagaimana cara menambahkan kolom yang bertambah pada kolom lain di tabel yang sama? , dan jawaban atas pertanyaan ini memerlukan sedikit perubahan pada jawaban atas dua pertanyaan sebelumnya, yang akan saya perhatikan jika perlu.

Karena perhitungan "periode istirahat pitcher" dan "perolehan lari rata-rata" tidak tergantung satu sama lain, saya merekomendasikan prosedur terpisah untuk masing-masing. Namun, karena hasil dari dua prosedur akan sering digunakan bersama-sama, saya merekomendasikan tabel awal yang umum untuk perhitungan, dan menyarankan pemfaktoran ulang pembuatan dan populasi tabel awal itu menjadi prosedur ketiga:

DELIMITER $$

-- DROP PROCEDURE pitcher_stats_reset $$

CREATE PROCEDURE pitcher_stats_reset()
BEGIN
  DROP TEMPORARY TABLE IF EXISTS pitcher_stats_temp;

  CREATE TEMPORARY TABLE pitcher_stats_temp
  (
    pitcher_id      char(10)    NOT NULL,
    game_date       date        NOT NULL,
    game_seq        int         NOT NULL,
    innings_pitched double      DEFAULT 0.0,
    ip_total        double      DEFAULT 0.0,
    earned_runs     INT         DEFAULT 0,
    er_total        INT         DEFAULT 0,
    std_era         DOUBLE      DEFAULT 0.0,
    starter_rest    INT         DEFAULT 0,
    CONSTRAINT pitcher_stats_temp_pk
      PRIMARY KEY (pitcher_id , game_date , game_seq )
  ) ENGINE=InnoDB;

  INSERT INTO pitcher_stats_temp
        (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;
END $$

DELIMITER ;

Versi sebelumnya menggunakan tabel yang normal dan persisten karena saya belum terbiasa dengan penanganan tabel sementara MySQL. Tabel sementara secara otomatis dijatuhkan ketika pengguna log off, merebut kembali ruang yang digunakan untuk data turunan yang dapat dibuat ulang sesuai kebutuhan. Menjatuhkan dan membuat ulang tabel sama dengan TRUNCATE ing (kecuali bahwa tabel tidak perlu ada sebelumnya) yang pada gilirannya jauh lebih cepat daripada DELETE tanpa syarat , menurut dokumen MySQL. Saya telah membuat perubahan beranotasi yang sesuai pada prosedur rata-rata yang diperoleh-berjalan juga.

Prosedur untuk menghitung waktu istirahat pitcher sekali lagi mengikuti idiom standar "control-break". Perhatikan bahwa kita membaca record pertama dan mengatur bidang kontrol sekali sebelum memasuki loop, kemudian dalam loop kita menguji kondisi keluar kita, memproses record "saat ini", membaca record "berikutnya", dan loop.

DROP PROCEDURE IF EXISTS pitcher_stats_rest_time;

DELIMITER $$

CREATE PROCEDURE pitcher_stats_rest_time()
  BEGIN
    DECLARE pit_id          CHAR(10);
    DECLARE prev_pit        CHAR(10);
    DECLARE gdate           DATE;
    DECLARE seq             INT;
    DECLARE prev_date       DATE;
    DECLARE rest_days       INT;
    DECLARE end_of_cursor   BOOLEAN;

    DECLARE no_table CONDITION FOR SQLSTATE '42S02';

    DECLARE c1 CURSOR FOR
      SELECT pitcher_id, game_date, game_seq
        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;

    SET end_of_cursor := FALSE;

    -- Read first record and initialize control fields
    OPEN c1;
    FETCH c1 INTO pit_id, gdate, seq;
    SET prev_date := 0;
    SET prev_pit := pit_id;

    fetch_loop: LOOP
      -- Test for end-of-cursor
      IF end_of_cursor THEN
        LEAVE fetch_loop;
      END IF;

      -- Test for change in control fields. If the pitcher changes,
      --  fake a change in the year to trigger the break.
      IF pit_id != prev_pit THEN
        SET prev_date := 0;
      END IF;

      IF YEAR(prev_date) = YEAR(gdate) THEN
        SET rest_days := DATEDIFF(gdate, prev_date);
      ELSE
        SET rest_days := 0;
      END IF;

      UPDATE pitcher_stats_temp
        SET starter_rest = rest_days
        WHERE pitcher_id = pit_id
          AND game_date = gdate
          AND game_seq = seq;

      -- After processing record, update control fields
      SET prev_date := gdate;
      SET prev_pit := pit_id;

      -- Read next record and repeat
      FETCH c1 INTO pit_id, gdate, seq;
    END LOOP;

    CLOSE c1;

  END $$

DELIMITER ;

Sedang digunakan, pitcher_stats_reset() dipanggil terlebih dahulu, untuk menginisialisasi tabel kerja. Setelah selesai, pitcher_stats_era() dan pitcher_stats_rest_time() dapat dipanggil berulang kali dalam urutan apa pun. Jika pitcher_stats_reset() tidak dipanggil terlebih dahulu, dua prosedur lainnya akan mengeluarkan pengingat sopan untuk melakukannya.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL menggabungkan dua kolom menjadi satu kolom

  2. Bagaimana cara memigrasi database SQL Server ke MySQL?

  3. Logis DAN operator di mySql REGEXP?

  4. MySQL - Menghapus Beberapa Tabel Tertentu Dari Database Besar

  5. Hibernate - ManyToOne &Inheritance / BERGABUNG / dipetakan Oleh