2013-09-20 22 views
5

Я изучал этот сайт, чтобы узнать, как сбрасывать результаты выражения select в массив, поэтому я могу выполнять итерацию по массиву. Однако мне не посчастливилось найти простой пример. Приведенный ниже код является примером того, что я сделал. Однако я не могу понять, как это сделать с помощью массива. Только строковая конструкция. Всякий раз, когда я пытаюсь присвоить результаты запроса массиву, я получаю эту ошибку в подзапросе (например, что-то вроде «array: = (select ... from sometable)», что я понимаю, но должен быть способ сделать это. заранее. (дополнение: псевдокод для того, что я предпочитаю под этим фактический кодом)..PostgreSQL - SELECT INTO ARRAY

DO 
$$ 
DECLARE 
    nRowCount   bigint; 
    i     record; 
BEGIN 

DROP TABLE IF EXISTS companies_sample_db_temp; 
CREATE TABLE companies_sample_db_temp (
col1  varchar 
, col2  varchar 
, col3  varchar 
); 

INSERT INTO companies_sample_db_temp VALUES ('McDonalds','Los Angeles','CA'); 
INSERT INTO companies_sample_db_temp VALUES ('Starbucks','Seattle','WA'); 
INSERT INTO companies_sample_db_temp VALUES ('Oracle','San Francisco','CA'); 

-- SELECT * FROM companies_sample_db_temp; 

FOR i IN 
    with a as 
    (
    SELECT 
    ARRAY[col1::text 
      , col2::text 
      , col3::text      
    ] as coltext 
    FROM companies_sample_db_temp AS my_arr 
) 
    select row_number() over(), coltext from a 
LOOP 
-- RAISE INFO 'nRowCount: %', nRowCount; 
    RAISE INFO 'Array Info: %', i.coltext[1]; 
END LOOP; 

END 
$$; 

/*********** Pseudo Code of what I'd rather do *******************/ 
DO 
$$ 
DECLARE 
    -- Assign results of this query to an array 
    my_arr := SELECT col1, col2,col3 FROM companies_sample_db_temp; 
    i     record; 

BEGIN 
-- Loop through an "array" not a table using a select statement. 
FOR i IN 
    -- Iterate through each row of the array 
    my_arr[i] -- Row from the select query 
    LOOP 
     -- Display an elements within a single array row 
     RAISE INFO 'Array Info: %', my_arr[i][1]; -- col1 
     RAISE INFO 'Array Info: %', my_arr[i][2]; -- col2 
     RAISE INFO 'Array Info: %', my_arr[i][3]; -- col3 
END LOOP; 
END $$; 

Надеется, что это проясняет вопрос

+1

Почему вы хотите массив, а не набор строк? Это SQL, наборы строк - это нормальная вещь, которую нужно перевернуть - или, предпочтительно, работать с операторами SQL и позволить СУБД решить, нужна ли вообще петля ... – IMSoP

+0

Очень хороший вопрос. Причина, по которой я предпочитаю использовать массив, связана с производительностью. Я буду первым, кто скажет, что я ошибаюсь в этом, так как я все еще новичок. Однако на других языках переменные памяти обычно значительно быстрее, чем наборы записей или таблицы. Если это не так, сообщите мне, где я могу найти информацию по этому вопросу (если вы знакомы с кем-либо). Мне не повезло. –

+0

На самом деле, наборы записей и таблицы очень часто бывают быстрее, чем «переменные памяти» (я предполагаю, что вы подразумеваете логику приложения вне базы данных здесь), если только программное обеспечение не разработано разработчиками «веб-масштаба», которые считают, что база данных представляет собой гигантский массив. (По общему признанию, последнее часто встречается.) –

ответ

1

Учитывая, что ваши рассуждения за попытку это «производительность», считаем следующие:

  1. Таблицы и строки (или в не-SQL-выражениях, отношения и кортежи) являются сообщениями Postgres's хлеб и масло; если они не были эффективными, это была бы довольно белая СУБД.
  2. «Преждевременная оптимизация», как правило, контрпродуктивным: чем больше времени вы проводите на ранней стадии вещей, которые вы думаете, мощь имеют влияние на производительность, тем меньше времени у вас есть позже, чтобы исправить вещи, которые сделать имеют влияние на производительность. Если вы инкапсулируете процесс в функцию, это довольно хорошее место, чтобы подчеркнуть простоту и ремонтопригодность, потому что позже вы можете заменить новую реализацию, если обнаружите, что это действительно создает проблемы.
  3. Достаточно редко для СУБД даже имеют типы массивов, и любая проблема, которая, как представляется, нуждается в цикле в функции базы данных, обычно может быть повторно создана как операция против набора данных, а решение превращено в SQL собственно. СУБД может решить использовать внутренний цикл, но в 99% случаев лучше принять это решение, чем вы.
  4. Вы упомянули «переменные памяти»; Я не совсем уверен, что вы подразумеваете под этим (все в памяти, когда оно работает), но похоже, что вы делаете довольно глубокие предположения о том, как разные типы данных будут работать «под капотом». Динамический массив и набор записей - это сложные структуры данных, которые необходимо будет управлять; нет основной причины в любом языке, почему один из них был бы более эффективным, за исключением того, что языки, как правило, оптимизированы для определенных случаев. (И, следовательно, см. Пункт 1.)
+0

Удивительный! Благодаря! Вы мне много подумали. Под «переменными памяти» я имел в виду вне структуры данных SQL. В цикле программирования языка программирования, отличном от SQL, ставятся циклы SQL в позор в производительности. Как только данные достигнут определенного размера, это, конечно, не имеет значения, но кажется, что вы знали, где я собираюсь с этим. Предположим, что если PostgreSQL не оптимизирует для массивов, то для моей конкретной ситуации не будет никакого преимущества. Поэтому вы поможете мне решить всю идею. –