Массивы
Срезы
В PostgreSQL также поддерживается возможность создания срезов при выборке из массива. Срез аналогичен обычному обращению к элементам по индексу, но он описывает интервал значений. Срез задается парой целочисленных индексов, разделенных двоеточием и заключенных в квадратные скобки. Например, конструкция [2:5] описывает второй, третий, четвертый и пятый элемент заданного массива. Результат среза возвращается в виде константы-массива, которая фактически описывает подмножество элементов исходного массива (впрочем, срез может содержать все элементы исходного массива).
В листинге 7.24 выбираются первые два элемента массива books в записях таблицы favorite_books. Хотя первая запись содержит только одно название книги, оно возвращается в виде массива из одного элемента.
Листинг 7.24. Выборка с использованием среза.
booktown=# SELECT books[l:2] FROM favorite_books; books {"The Hitchhiker's Guide to the Galaxy"} {"The Hobbit"."Kitten, Squared"} (2 rows)
В PostgreSQL 7.1.x использование срезов в многомерных массивах иногда приводит к непредсказуемым последствиям. По этой причине, пока не будут внесены исправления, при работе с многомерными массивами рекомендуется обращаться к элементам по конкретным значениям индексов.
Определение количества элементов
Чтобы узнать количество значении, хранящихся в массиве, следует воспользоваться функцией array_dims(). В качестве параметра функции передается идентификатор – имя поля-массива, для которого вызывается функция. Результат возвращается в виде строки, содержащей описание массива в синтаксисе среза. В листинге 7.25 приведен пример вызова функции array_dims() для поля books таблицы favorite_books.
Листинг 7.25. Функция array_dims().
booktown=# SELECT array_dims(books) FROM favorite_books; array_dims [1:1] [1:2] (2 rows)
Обновление данных в полях-массивах
Существует три варианта модификации данных в полях-массивах.
- Полная модификация. Все содержимое массива заменяется новыми данными, заданными в виде массива-константы.
- Модификация среза. Срез (то есть интервальное подмножество элементов) заменяется новыми данными, заданными в виде массива-константы. Количество элементов в константе должно соответствовать количеству элементов в обновляемом срезе.
- Модификация элемента. Отдельный элемент массива заменяется новой константой, относящейся к базовому типу данных массива. Элемент задается индексом. В первом случае количество элементов в новом массиве может не совпадать с количеством элементов в существующем массиве. Допустим, работник с кодом id=102 хочет добавить данные о новой книге в список, хранящийся в таблице favorite_books. Команда UPDATE, приведенная в листинге 7.26, заменяет все текущее содержимое массива.
Листинг 7.26. Полная модификация массива.
booktown=# UPDATE favorite_books booktown-# SET books='{"The HitchhikerVs Guide to the Galaxy", booktown'# "The Restaurant at the End of the Universe"}' booktown-# WHERE employeejd = 102; UPDATE 1
Способ, продемонстрированный в листинге 7.26, подходит и для модификации среза массива. Для этого в конец идентификатора поля добавляется определение среза, например, books[1:3] означает первый, второй и третий элементы массива. Впрочем, на практике чаще возникает задача замены не всего массива и не среза, а отдельных элементов.
При обновлении отдельного элемента к идентификатору поля присоединяется индекс, определяющий конкретный обновляемый элемент. В листинге 7.27 приведен пример обновления первого элемента в массиве books таблицы favorite_books.
Листинг 7.27. Модификация отдельного элемента:
booktown=# SELECT books[l] FROM favorite_books; books The Hitchhiker's Guide to the Galaxy The Hobbit (2 rows) booktown=# UPDATE favorite_books booktown-# SET books[l] = 'There and Back Again: A HobbitVs Holiday' booktown-# WHERE books[l] = 'The Hobbit'; UPDATE 1 booktown=# SELECT books[l] FROM favorite_books; books The Hitchhiker's Guide to the Galaxy There and Back Again: A Hobbit's Holiday (2 rows)