sql >> Databáze >  >> RDS >> Mysql

Jak mohu procházet všechny řádky tabulky? (MySQL)

Protože návrh smyčky implikuje požadavek na řešení typu procedury. Tady je můj.

Jakýkoli dotaz, který funguje na libovolném jednotlivém záznamu převzatém z tabulky, lze zabalit do procedury, aby proběhl každým řádkem tabulky takto:

Nejprve odstraňte jakoukoli existující proceduru se stejným názvem a změňte oddělovač, aby se váš SQL nepokoušel spustit každý řádek, když se pokoušíte napsat proceduru.

DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;

Pak je zde postup podle vašeho příkladu (tabulka_A a tabulka_B použité pro přehlednost)

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;
;;

Pak nezapomeňte resetovat oddělovač

DELIMITER ;

A spusťte nový postup

CALL ROWPERROW();

Na řádku „INSERT INTO“, který jsem jednoduše zkopíroval z vašeho vzorového požadavku, můžete dělat, co chcete.

POZORNĚ si všimněte, že zde použitý řádek "INSERT INTO" zrcadlí řádek v otázce. Podle komentářů k této odpovědi se musíte ujistit, že váš dotaz je syntakticky správný pro kteroukoli verzi SQL, kterou používáte.

V jednoduchém případě, kdy je vaše pole ID zvýšeno a začíná na 1, řádek v příkladu může vypadat takto:

INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A WHERE ID=i;

Nahrazení řádku "SELECT COUNT" znakem

SET n=10;

Umožní vám otestovat váš dotaz pouze na prvních 10 záznamu v tabulce_A.

Poslední věc. Tento proces je také velmi snadné vnořit do různých tabulek a byl to jediný způsob, jak jsem mohl provést proces na jedné tabulce, který dynamicky vkládal různé počty záznamů do nové tabulky z každého řádku nadřazené tabulky.

Pokud potřebujete, aby běžel rychleji, zkuste jej nastavit na základě, pokud ne, pak je to v pořádku. Můžete také přepsat výše uvedené ve formě kurzoru, ale nemusí to zlepšit výkon. např.:

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;
;;

Nezapomeňte deklarovat proměnné, které budete používat, jako stejný typ jako proměnné z dotazovaných tabulek.

Moje rada je používat dotazy založené na množinách, když můžete, a používat pouze jednoduché smyčky nebo kurzory, pokud musíte.



  1. Jak mohu provést SELECT DISTINCT na všech polích kromě BLOB?

  2. Ruby on Rails 3 Nelze se připojit k místnímu serveru MySQL přes socket '/tmp/mysql.sock' na OSX

  3. Ověření hesla Postgres se nezdařilo

  4. Funkce zabezpečení Spotlight Cloud – Odstraňte literály