Saya memiliki tabel A dan ada satu ID kunci utama.
Sekarang saya ingin menelusuri semua baris di A.
Saya menemukan sesuatu seperti 'untuk setiap catatan di A', tetapi tampaknya ini bukan cara Anda melakukannya di MySQL.
Masalahnya adalah untuk setiap baris saya ingin mengambil bidang dan mengubahnya, memasukkannya ke dalam tabel lain dan kemudian memperbarui beberapa bidang baris. Saya dapat memasukkan bagian yang dipilih dan menyisipkan ke dalam satu pernyataan, tetapi saya juga tidak tahu cara mendapatkan pembaruan di sana. Jadi saya ingin mengulang. Dan untuk latihan saya tidak ingin menggunakan yang lain selain MySQL.
edit
Saya sangat menghargai contoh.
Dan solusi yang tidak perlu dimasukkan ke dalam prosedur.
edit 2
oke pikirkan skenario ini:
Tabel A dan B, masing-masing dengan kolom ID dan VAL.
Sekarang ini adalah kode pseudo untuk apa yang ingin saya lakukan:
for(each row in A as rowA)
{
insert into B(ID, VAL) values(rowA[ID], rowA[VAL]);
}
pada dasarnya menyalin konten A ke B menggunakan loop.
(ini hanya contoh yang disederhanakan, tentu saja Anda tidak akan menggunakan loop untuk ini.)}
Jawaban:
Karena saran perulangan menyiratkan permintaan untuk solusi tipe prosedur. Ini milikku.
Kueri apa pun yang bekerja pada satu rekaman yang diambil dari tabel bisa dibungkus dalam prosedur untuk membuatnya berjalan melalui setiap baris tabel seperti:
DROP PROCEDURE IF EXISTS ROWPERROW; DELIMITER ;;
Lalu inilah prosedur sesuai contoh Anda (table_A dan table_B digunakan untuk kejelasan)
CREATE PROCEDURE ROWPERROW() BEGIN DECLARE n INT DEFAULT 0; DECLARE i INT DEFAULT 0; SELECT COUNT(*) FROM table_A INTO n; SET i=0; WHILE i<n DO INSERT INTO table_B(ID, VAL) SELECT (ID, VAL) FROM table_A LIMIT i,1; SET i = i + 1; END WHILE; End; ;;
Kemudian jangan lupa untuk mengatur ulang pembatas
Dan jalankan prosedur baru
CALL ROWPERROW();
Anda dapat melakukan apapun yang Anda suka di baris "INSERT INTO" yang saya salin dari permintaan contoh Anda.
Perhatikan dengan HATI-HATI bahwa baris "SISIPKAN KE" yang digunakan di sini mencerminkan baris dalam pertanyaan. Sesuai dengan komentar untuk jawaban ini, Anda perlu memastikan bahwa kueri Anda benar secara sintaksis untuk versi SQL mana pun yang Anda jalankan.
Dalam kasus sederhana di mana bidang ID Anda bertambah dan dimulai pada 1, baris dalam contoh dapat menjadi:
INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A WHERE ID=i;
Mengganti baris "SELECT COUNT" dengan
SET n=10;
Akan membiarkan Anda menguji kueri Anda pada 10 catatan pertama di table_A saja.
Satu hal terakhir. Proses ini juga sangat mudah untuk disarangkan di tabel yang berbeda dan merupakan satu-satunya cara saya dapat melakukan proses pada satu tabel yang secara dinamis memasukkan jumlah record yang berbeda ke dalam tabel baru dari setiap baris tabel induk.
Jika Anda membutuhkannya untuk berjalan lebih cepat maka pastikan untuk membuatnya berdasarkan, jika tidak maka ini bagus. Anda juga dapat menulis ulang di atas dalam bentuk kursor tetapi mungkin tidak meningkatkan kinerja. misalnya:
DROP PROCEDURE IF EXISTS cursor_ROWPERROW; DELIMITER ;; CREATE PROCEDURE cursor_ROWPERROW() BEGIN DECLARE cursor_ID INT; DECLARE cursor_VAL VARCHAR; DECLARE done INT DEFAULT FALSE; DECLARE cursor_i CURSOR FOR SELECT ID,VAL FROM table_A; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cursor_i; read_loop: LOOP FETCH cursor_i INTO cursor_ID, cursor_VAL; IF done THEN LEAVE read_loop; END IF; INSERT INTO table_B(ID, VAL) VALUES(cursor_ID, cursor_VAL); END LOOP; CLOSE cursor_i; END; ;;
Ingatlah untuk mendeklarasikan variabel yang akan Anda gunakan sebagai jenis yang sama dengan yang ada di tabel yang ditanyakan.
Saran saya adalah menggunakan kueri berbasis set ketika Anda bisa, dan hanya gunakan loop atau kursor sederhana jika perlu.
sumber
LIMIT i,1000;
danset i = i + 1000
;Anda harus benar-benar menggunakan solusi berbasis set yang melibatkan dua kueri (penyisipan dasar):
INSERT INTO TableB (Id2Column, Column33, Column44) SELECT id, column1, column2 FROM TableA UPDATE TableA SET column1 = column2 * column3
Dan untuk transformasi Anda:
INSERT INTO TableB (Id2Column, Column33, Column44) SELECT id, column1 * column4 * 100, (column2 / column12) FROM TableA UPDATE TableA SET column1 = column2 * column3
Sekarang jika transformasi Anda lebih rumit dari itu dan melibatkan banyak tabel, posting pertanyaan lain dengan detailnya.
sumber
KURSOR adalah opsi di sini, tetapi umumnya tidak disukai karena sering kali tidak memanfaatkan mesin kueri dengan baik. Pertimbangkan untuk menyelidiki 'SET Based Queries' untuk melihat apakah Anda dapat mencapai apa yang ingin Anda lakukan tanpa menggunakan CURSOR.
sumber
Contoh Pak Ungu yang saya gunakan di pemicu mysql seperti itu,
begin DECLARE n INT DEFAULT 0; DECLARE i INT DEFAULT 0; Select COUNT(*) from user where deleted_at is null INTO n; SET i=0; WHILE i<n DO INSERT INTO user_notification(notification_id,status,userId)values(new.notification_id,1,(Select userId FROM user LIMIT i,1)) ; SET i = i + 1; END WHILE; end
sumber
Use this: $stmt = $user->runQuery("SELECT * FROM tbl WHERE ID=:id"); $stmt->bindparam(":id",$id); $stmt->execute(); $stmt->bindColumn("a_b",$xx); $stmt->bindColumn("c_d",$yy); while($rows = $stmt->fetch(PDO::FETCH_BOUND)) { //---insert into new tble }
sumber