Как я могу перебирать все строки таблицы? (MySQL)


У меня есть таблица A и есть один идентификатор первичного ключа.

теперь я хочу пройти через все строки А.

Я нашел что-то вроде "для каждой записи в A", но это, кажется, не так, как вы это делаете в MySQL.

для каждой строки Я хочу взять поле и преобразовать его, вставить его в другую таблицу, а затем обновить некоторые поля строки. Я могу поместить часть select и insert в один оператор, но я не знаю, как получить обновление там, как что ж. Поэтому я хочу сделать петлю. И для практики я не хочу использовать ничего, кроме MySQL.

edit

Я был бы признателен за пример.

и решение, которое не нужно приводить в порядок.

edit 2

хорошо подумайте об этом сценарии:

таблицы A и B, каждая с полями ID и VAL.

теперь это псевдо-код для того, что я хочу делать:

for(each row in A as rowA)
{
  insert into B(ID, VAL) values(rowA[ID], rowA[VAL]);
}

в основном копирование содержимого A в B с помощью цикла.

(это просто упрощенный пример, конечно, вы бы не использовать цикл для этого.) }

5 57

5 ответов:

так как предложение цикла подразумевает запрос на решение типа процедуры. Вот моя.

любой запрос, который работает с любой отдельной записью, взятой из таблицы, может быть обернут в процедуру, чтобы она проходила через каждую строку таблицы следующим образом:

DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;

тогда вот процедура в соответствии с вашим примером (table_A и table_B используется для ясности)

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) VALUES(ID, VAL) FROM table_A LIMIT i,1;
  SET i = i + 1;
END WHILE;
End;
;;

тогда не забудьте сбросить разделитель

DELIMITER ;

и запустить новый процедура

CALL ROWPERROW();

вы можете делать все, что вам нравится в строке "вставить в", которую я просто скопировал из вашего примера запроса.

обратите внимание, что строка" вставить в", используемая здесь, отражает линию в вопросе. В соответствии с комментариями к этому ответу вам нужно убедиться, что ваш запрос синтаксически корректен для какой бы версии SQL вы ни работали.

в простом случае, когда поле ID увеличивается и начинается с 1 строки в Примере может стать:

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

замена строки "SELECT COUNT" на

SET n=10;

позволит вам проверить ваш запрос на первой записи 10 в table_A только.

и последнее. Этот процесс также очень легко вложить в разные таблицы и был единственным способом, которым я мог выполнить процесс на одной таблице, которая динамически вставляла разные числа записей в новую таблицу из каждой строки родительской таблицы.

Если вам нужно, чтобы он работал быстрее, то конечно попробуйте сделать это установить, если нет, то это нормально. Вы также можете переписать выше в форме курсора, но это не может улучшить производительность. например:

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

Не забудьте объявить переменные, которые вы будете использовать в качестве того же типа, что и те из запрашиваемых таблиц.

мой совет-идти с заданными запросами, когда вы можете, и использовать только простые циклы или курсоры, если вам нужно.

вы действительно должны использовать решение на основе набора, включающее два запроса (базовая вставка):

INSERT INTO TableB (Id2Column, Column33, Column44)
SELECT id, column1, column2 FROM TableA

UPDATE TableA SET column1 = column2 * column3

и для преобразования:

INSERT INTO TableB (Id2Column, Column33, Column44)
SELECT 
    id, 
    column1 * column4 * 100, 
    (column2 / column12) 
FROM TableA

UPDATE TableA SET column1 = column2 * column3

теперь, если ваше преобразование сложнее, чем это, и включает в себя несколько таблиц, отправьте еще один вопрос с подробностями.

курсоры-это вариант здесь, но обычно нахмурился, поскольку они часто не делают лучшее использование механизма запросов. Рассмотрите возможность изучения "запросов на основе набора", чтобы узнать, можете ли вы достичь того, что вы хотите сделать, не используя курсор.

пример г-на пурпурного я использовал в MySQL триггер, как это,

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