Ошибка произошла из-за того, что предельный размер для переменной составляет 1 МБ .
Относительно l oop для обработки пакетов. В качестве ссылки вы можете использовать следующее SQL:
DECLARE offset_ INT64 DEFAULT 1; -- OFFSET starts in 1 BASED on ROW NUMBER ()
DECLARE limit_ INT64 DEFAULT 500; -- Size of the chunks to be processed
DECLARE size_ INT64 DEFAULT 7000; -- Size of the data (used for the condition in the WHILE loop)
-- Table to be processed. I'm creating this new temporary table to use it as an example
CREATE TEMPORARY TABLE IF NOT EXISTS data_numbered AS (
SELECT *, ROW_NUMBER() OVER() row_number
FROM (SELECT * FROM `bigquery-public-data.stackoverflow.users` LIMIT 7000)
);
-- WHILE loop
WHILE offset_ < size_ DO
IF offset_ = 1 THEN -- OPTIONAL, create the temporary table in the first iteration
CREATE OR REPLACE TEMPORARY TABLE temp_table AS (
SELECT * FROM data_numbered
WHERE row_number BETWEEN offset_ AND offset_ + limit_ - 1 -- Use offset and limit to control the chunks of data
);
ELSE
-- This is the same query as above.
-- Each iteration will fill the temporary table
-- Iteration
-- 501 - 1000
-- 1001 - 1500
-- ...
INSERT INTO temp_table (
SELECT * FROM data_numbered WHERE row_number BETWEEN offset_ AND offset_ + limit_ - 1 -- -1 because BETWEEN is inclusive, so it helps to avoid duplicated values in the edges
);
END IF;
-- Adjust the offset_ variable
SET offset_ = offset_ + limit_;
END WHILE;
Одной из проблем при выполнении этого l oop является то, что вы не можете использовать переменные в предложении LIMIT и OFFSET. Итак, я использовал ROW_NUMBER () для создания столбца, который я мог бы использовать для обработки с предложением WHERE:
WHERE row_number BETWEEN offset_ AND offset_ + limit_
Если вы хотите узнать больше о ROW_NUMBER (), я рекомендую проверить это SO ответ .
Наконец, если вы хотите использовать этот подход, учтите, что существуют некоторые предостережения, такие как использование сценариев Beta и возможные проблемы с квотами в зависимости от того, как часто вы вставляете данные во временную таблицу. Кроме того, поскольку запрос изменяется в каждой итерации, при первом запуске, и он не кэшируется, bytes_processed будет number_of_iterations * byte_size таблицы