Руководство по sql: как лучше писать запросы (часть 1)
Содержание:
- Использование запросов в PHP
- MySQL WHERE clause examples
- 1) Using MySQL clause with equal operator example
- 2) Using MySQL clause with operator
- 3) Using MySQL clause with operator
- 4) Using MySQL with operator example
- 5) Using MySQL with the operator example
- 6) Using MySQL clause with the operator example
- 7) Using MySQL clause with the operator
- 8) Using MySQL clause with comparison operators
- Простые mysql запросы
- Select and Filter Data With MySQLi
- Оператор create table: создание таблиц
- MySQL
- Хранимая процедура для создания представления одной таблицы
- Простые примеры использования SELECT
- Внимание
- Аналоги аналитических функций
- 1) ROW_NUMBER() OVER(ORDER BY order_id)
- 2) ROW_NUMBER() OVER(PARTITION BY group_id ORDER BY order_id)
- 3) SUM(value) OVER(PARTITION BY group_id ORDER BY order_id)
- 4) LAG(value) OVER(PARTITION BY group_id ORDER BY order_id)
- 5) COUNT(*) OVER(PARTITION BY group_id)
- 6) MAX(value) OVER(PARTITION BY group_id)
- 7) COUNT(DISTINCT value) OVER(PARTITION BY group_id)
- Агрегатные функции
- Select Data With PDO (+ Prepared Statements)
- Проверка наличия совпадения
Использование запросов в PHP
Подключаемся к базе данных:
mysql_connect (‘localhost’, ‘login’, ‘password’) or die («MySQL connect error»);
mysql_select_db (‘db_name’);
mysql_query(«SET NAMES ‘utf8′»);
* где подключение выполняется к базе на локальном сервере (localhost); учетные данные для подключения — login и password (соответственно, логин и пароль); в качестве базы используется db_name; используемая кодировка UTF-8.
Также можно создать постоянное подключение:
mysql_pconnect (‘localhost’, ‘login’, ‘password’) or die («MySQL connect error»);
* однако есть вероятность достигнуть максимально разрешенного лимита хостинга. Данным способом стоит пользоваться на собственных серверах, где мы сами можем контролировать ситуацию.
Завершить подключение:
mysql_close();
* в PHP выполняется автоматически, кроме постоянных подключений (mysql_pconnect).
Запрос к MySQL (Mariadb) в PHP делается функцией mysql_query(), а извлечение данных из запроса — mysql_fetch_array():
$result = mysql_query(«SELECT * FROM users»);
while ($mass = mysql_fetch_array($result)) {
echo $mass . ‘<br>’;
}
* в данном примере выполнен запрос к таблице users. Результат запроса помещен в переменную $result. Далее используется цикл while, каждая итерация которого извлекает массив данных и помещает его в переменную $mass — в каждой итерации мы работаем с одной строкой базы данных.
Используемая функция mysql_fetch_array() возвращает ассоциативный массив, с которым удобно работать, но есть еще альтернатива — mysql_fetch_row(), которая возвращает обычный нумерованный массив.
MySQL WHERE clause examples
We’ll use the table from the sample database for the demonstration.
1) Using MySQL clause with equal operator example
The following query uses the clause to find all employees whose job titles are :
In this example, the statement examines all rows of the table and selects only row whose value in the column is .
2) Using MySQL clause with operator
The following example uses the clause to find employees whose job titles are and office codes are 1:
In this example, the expression in the clause uses the operator to combine two conditions:
The operator evaluates to only if both expressions evaluate to . Therefore, the query returns rows whose values in the column is and is 1.
3) Using MySQL clause with operator
This query finds employees whose job title is or employees who locate the office with office code 1:
The operator evaluates to only if one of the expression evaluates to :
Therefore, the query returns any employee who has the job title Sales Rep or office code 1.
4) Using MySQL with operator example
The operator returns if a value is in a range of values:
The following query finds employees who locate in offices whose office code is from 1 to 3:
5) Using MySQL with the operator example
The operator evaluates to if a value matches a specified pattern. To form a pattern, you use and wildcards. The wildcard matches any string of zero or more characters while the wildcard matches any single character.
This query finds employees whose last names end with the string :
6) Using MySQL clause with the operator example
The operator returns if a value matches any value in a list.
The following example uses the clause with the operator to find employees who locate in the office with office code 1.
7) Using MySQL clause with the operator
To check if a value is or not, you use the operator, not the equal operator (). The operator returns if a value is .
In the database world, is a marker that indicates a piece of information is missing or unknown. It is not equivalent to the number 0 or an empty string.
This statement uses the clause with the operator to get the row whose value in the column is :
8) Using MySQL clause with comparison operators
The following table shows the comparison operators that you can use to form the expression in the clause.
The following query uses the not equal to (<>) operator to find all employees who are not the :
The following query finds employees whose office code is greater than 5:
The following query returns employees with office code less than or equal 4 (<=4):
In this tutorial, you have learned how to use the MySQL clause to filter rows based on conditions.
- Was this tutorial helpful?
Простые mysql запросы
Зная структуру БД, таблиц в БД и полей, можно посылать следующие запросы в MySQL.
слово select, говорит само за себя, и становится понятно, что пользуясь данными запросами, мы будем выбирать (читать) информацию из БД. |
|
SELECT count(*) FROM table_name; Выведет количество всех записей в таблице |
|
SELECT * FROM table_name; Выбирает все записи из таблицы БД |
|
SELECT * FROM table_name LIMIT 2,3; Выбирает 3 записи из таблицы, начиная с 2 записи. Этот запрос полезен при создании блока страниц навигации. |
|
SELECT * FROM person ORDER BY number; Выберет все записи из таблицы person в порядке возрастания значений поля number. |
|
SELECT * FROM person ORDER BY number DESC; Выбирает все записи из person, но уже в порядке убывания (т.е. в обратном порядке). |
|
SELECT * FROM person ORDER BY number LIMIT 5; Выбирает 5 записей из таблицы person, в порядке возрастания. |
|
SELECT * FROM person WHERE name=’Anna’; Выбирает все записи из таблицы person, где поле name соответствует значению Anna. |
|
SELECT * FROM person WHERE name LIKE ‘An%’; Выбирает все записи из таблицы person, в которой значения поля nameначинаются с An. |
|
SELECT * FROM person WHERE name LIKE ‘%na’ ORDER BY number ; Выбирает все записи из таблицы person, где name заканчивается на na, и упорядочивает записи в порядке возрастания значения number. |
|
SELECT name, last_name FROM person; Выбирает все значения полей name и last_name из таблицы person. |
|
SELECT DISTINCT site FROM table_name; Выбирает уникальные (DISTINCT) значения поля site из таблицы table_name. Например, при 5 значениях поля site: sitear.ru, sitear.ru, sitear.ru, yaveterinar.ru, wi-korporaciya.ru; выведет только 3 уникальные значения: sitear.ru, yaveterinar.ru, wi-korporaciya.ru; |
|
SELECT * from person where age in (12,15,18); Выведет все записи таблицы person в которых значения поля age будет равно 12 или 15 или 18. |
|
select max(age) from person; Выберет максимальное значение age из таблицы person. |
|
select name, min(age) from person; Выберет минимальное значение age из таблицы person. |
|
данные запросы позволяют вставить запись в таблицу БД. Другими словами создать строку в таблице или добавить информацию в таблицу БД. |
|
insert into table_name(site, description) values (‘sitear.ru’, ‘SiteAR – создание сайтов’) Вставит в таблицу table_name, а точнее в поля site и description данной таблицы, соответствующие значения. |
|
направлены на изменение уже имеющихся данных в таблице БД. |
|
update table_name set site = ‘domain.com’ where id = ‘3’ Изменяет значение поля site на domain.com в таблице table_name где id равен 3. |
|
delete from table_name where id = ‘3’ Удаляет запись из table_name где id равен 3. |
Select and Filter Data With MySQLi
The following example selects the id, firstname and lastname columns from the MyGuests
table where the lastname is «Doe», and displays it on the page:
Example (MySQLi Object-oriented)
<?php$servername = «localhost»;$username = «username»;$password = «password»;$dbname = «myDB»;// Create connection$conn = new mysqli($servername, $username, $password, $dbname);// Check connectionif ($conn->connect_error) { die(«Connection failed: » . $conn->connect_error);
} $sql = «SELECT id, firstname, lastname FROM MyGuests WHERE
lastname=’Doe'»;$result = $conn->query($sql);if ($result->num_rows > 0) { // output data of each row while($row = $result->fetch_assoc()) { echo «id: » . $row. » — Name: » . $row. » » . $row. «<br>»;
}} else { echo «0 results»;}
$conn->close();
?>
Code lines to explain from the example above:
First, we set up the SQL query that selects the id, firstname and lastname columns from the MyGuests
table where the lastname is «Doe». The next line of code runs the query and puts the resulting data into a
variable called $result.
Then, the checks if there are more than zero
rows returned.
If there are more than zero rows returned, the
function puts all the results into an associative array that we can loop
through. The loop loops through the result set and outputs the data from
the id, firstname and lastname columns.
The following example shows the same as the example above, in the MySQLi procedural way:
Example (MySQLi Procedural)
<?php$servername = «localhost»;$username = «username»;$password = «password»;$dbname = «myDB»;// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die(«Connection failed: » . mysqli_connect_error());}$sql = «SELECT id, firstname, lastname FROM MyGuests
WHERE lastname=’Doe'»;$result = mysqli_query($conn, $sql);if (mysqli_num_rows($result) > 0) { // output data of each row
while($row = mysqli_fetch_assoc($result)) { echo «id: » . $row. » — Name: » . $row. » » . $row. «<br>»;
}} else { echo «0 results»;}mysqli_close($conn);
?>
You can also put the result in an HTML table:
Example (MySQLi Object-oriented)
<?php$servername = «localhost»;$username = «username»;$password = «password»;$dbname = «myDB»;// Create connection$conn = new mysqli($servername, $username, $password, $dbname);// Check connectionif ($conn->connect_error) { die(«Connection failed: » . $conn->connect_error);
} $sql = «SELECT id, firstname, lastname FROM MyGuests WHERE
lastname=’Doe'»;$result = $conn->query($sql);if ($result->num_rows > 0) { echo «<table><tr><th>ID</th><th>Name</th></tr>»;
// output data of each row while($row = $result->fetch_assoc()) { echo «<tr><td>».$row.»</td><td>».$row.» «.$row.»</td></tr>»;
} echo «</table>»;} else { echo «0 results»;}
$conn->close();
?>
Оператор create table: создание таблиц
Создав новую БД, сообщим MySQL, что теперь мы собираемся работать именно с ней.
Выбор активной БД выполняется командой:
Пришло время создать первые таблицы!
Для ведения дневника по всем правилам, понадобится создать три таблицы: города (cities), пользователи (users) и записи о погоде (weather_log).
В подразделе «Запись» этой главы описано, как должна выглядеть структура таблицы weather_log. Переведём это описание на язык SQL:
Чтобы ввести многострочную команду в командной строке используйте символ в конце каждой строки (кроме последней).
Теперь создадим таблицу городов:
MySQL может показать созданную таблицу, если попросить об этом командой: .
В ответе будут перечислены все поля таблицы, их тип и другие характеристики.
Первичный ключ
В примере с созданием новой таблицы при перечислении необходимых полей первым полем идёт .
Это поле называется первичным ключом. Обязательно создавать первичный ключ в каждой таблице.
Первичный ключ — это особенное поле, в котором сохраняется уникальный идентификатор записи. Он нужен, чтобы у программиста и базы данных всегда была возможность однозначно обратиться к одной конкретной записи для её чтения, обновления или удаления.
Если назначить поле первичным ключом, то БД будет следить за тем, чтобы значение в этом поле больше не повторялось в таблице.
А если ещё и добавить аттрибут , то MySQL при добавлении новых записей будет заполнять это поле сама. будет играть роль счётчика — каждая новая запись в таблице получит значение на единицу больше максимального существующего значения.
MySQL
Существует множество различных реляционных СУБД. Самая известная СУБД — это Microsoft Access, входящая в состав офисного пакета приложений Microsoft Office.
Нет никаких препятствий для использования в качестве СУБД MS Access, но для задач веб-программирования гораздо лучше подходит альтернативная программа — MySQL.
В отличие от MS Access, MySQL абсолютно бесплатна, может работать на серверах с Linux, обладает гораздо большей производительностью и безопасностью, что делает её идеальным кандидатом на роль базы данных в веб-разработке.
Подавляющее большинство сайтов и приложений на PHP используют в качестве СУБД именно MySQL.
Хранимая процедура для создания представления одной таблицы
Хранимая процедура принимает два аргумента:
- tbl_name: имя таблицы, для которой создаётся VIEW;
- db_pattern_re: регулярное выражение для исключающей фильтрации баз данных, которые будут включены в VIEW.
A) Сначала надо объявить курсор для итеративного обхода всех БД, включённых в представление. Чтобы отфильтровать только те БД, которые нам нужны, используем регулярное выражение db_pattern_re. Обработчик CONTINUE HANDLER позаботится о том, чтобы цикл остановился после итеративного обхода всех найденных БД.
B) Инициализируем переменную all_dbs_view, содержащую нашу полную инструкцию CREATE VIEW. Переменная может оказаться довольно длинной (LONGTEXT), в зависимости от числа прошедших фильтрацию БД.
C) Теперь открываем курсор и начинаем итеративный обход каждой прошедшей фильтрацию БД. Оператор IF выполнит проверку на наличие переменной all_dbs_done на каждом этапе. При запуске обработчика CONTINUE HANDLER переменная будет иметь значение 1.
D) Первая итерация не требует ставить в начало UNION ALL, а вот все последующие будут ставить. Следующая строчка конкатенирует, то есть добавляет текущий оператор SELECT, содержащий все записи из таблицы БД конкретного пользователя:
E) Прежде чем создавать VIEW, необходимо убедиться, что предыдущее (если оно существовало) удалено.
F) И, наконец, запускаем саму инструкцию, создающую VIEW.
Теперь можно выполнить процедуру создания представления VIEW одной таблицы:
Простые примеры использования SELECT
Синтаксис:
> SELECT <fields1> FROM <table>
* где fields1 — поля для выборки через запятую, также можно указать все поля знаком *; table — имя таблицы, из которой вытаскиваем данные; conditions — условия выборки; fields2 — поле или поля через запятую, по которым выполнить сортировку; count — количество строк для выгрузки.
* запрос в квадратных скобках не является обязательным для выборки данных.
> SELECT * FROM users
* в данном примере мы получаем список всех записей из таблицы users.
2. Выборка данных с объединением двух таблиц (JOIN)
SELECT u.name, r.* FROM users u JOIN users_rights r ON r.user_id=u.id
* в данном примере идет выборка данных с объединением таблиц users и users_rights. Объединяются они по полям user_id (в таблице users_rights) и id (users). Извлекается поле name из первой таблицы и все поля из второй.
3. Выборка с интервалом по времени и/или дате
а) известна точка начала и определенный временной интервал:
> SELECT * FROM users WHERE date >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
* будут выбраны данные за последний час (поле date).
б) известны дата начала и дата окончания:
> SELECT * FROM users WHERE date >= ‘2017-10-25’ AND date <= ‘2017-11-25’
* выбираем данные в промежутке между 25.10.2017 и 25.11.2017.
в) известны даты начала и окончания + время:
> SELECT * FROM users WHERE DATE(date) BETWEEN ‘2018-03-25 00:15:00’ AND ‘2018-04-25 15:33:09’;
* выбираем данные в промежутке между 25.03.2018 0 часов 15 минут и 25.04.2018 15 часов 33 минуты и 9 секунд.
г) вытаскиваем данные за определенные месяц и год:
> SELECT * FROM study WHERE MONTH(date) = 4 AND YEAR(date) = 2018
* извлечем данные, где в поле date присутствуют значения для апреля 2018 года.
4. Выборка максимального, минимального и среднего значения
> SELECT max(area), min(area), avg(area) FROM country
* max — максимальное значение; min — минимальное; avg — среднее.
5. Использование длины строки
> SELECT * FROM users WHERE CHAR_LENGTH(name) = 5;
* данный запрос должен показать всех пользователей, имя которых состоит из 5 символов.
6. Использование лимитов (LIMIT)
Применяется для ограничения количества выводимых результатов. Синтаксис:
<основной запрос> LIMIT <число1>
* где число1 — сколько результатов вернуть; число2 — сколько результатов пропустить, необязательный параметр — если его не писать, то отсчет начнется с первой строки.
а) извлечь максимум 15 строк:
> SELECT * FROM users LIMIT 15;
б) выбрать строки с 16 по 25 (запрос со смещением):
> SELECT * FROM users LIMIT 15, 10;
* 15 строк пропускаем, 10 извлекаем.
Внимание
Как и в любом программном решении, здесь есть подводные камни, о которых мы ещё не упоминали.
1) При выполнении команды-SQL для создания VIEW сервер MySQL может выбрасывать исключение вроде такого:
Наше решение было таким:
У вас это значение (2800) может отличаться в зависимости от количества арендаторов.
2) При выполнении запросов с условием на конкретном арендаторе
можете получить исключения (в зависимости от того, как вы создавали базу данных):
Решение — смена кодировки (символов) имени базы данных при создании представления. Добавляем вызов функции CONVERT в операторе SELECT:
Вместо используйте значение, заданное вами для кодирования при создании базы данных.
3) Время ожидания подключения тоже может стать проблемой. На создание всех этих представлений может потребоваться время. В нашем случае на это ушло 5 минут. Так что позаботьтесь о том, чтобы время ожидания подключения в вашем клиенте было достаточным.
4) Лучше готовить VIEW и выполнять запросы на сервере реплики, чтобы не перегружать рабочие серверы. Иначе запросы очень быстро могут стать тяжёлыми.
5) Для тестирования этого метода использовался сервер MySQL Community Server 5.7.20.
- Как использовать Flutter с SQLite
- Инъекция SQL: руководство для начинающих
- Руководство по анализу данных с SQL
Перевод статьи Valentin Iljaž: Querying multiple MySQL databases at once
Аналоги аналитических функций
Переменные также можно использовать для замены аналитических функций. Далее несколько примеров. Для простоты будем считать, что все поля NOT NULL, а сортировка и партиционирование (PARTITION BY) происходят по одному полю. Использование NULL значений и более сложных сортировок сделает примеры более громоздкими, но суть не поменяет.
Для примеров создадим таблицу TestTable:
где
group_id – идентификатор группы (аналог окна аналитической функции);
order_id – уникальное поле, по которому будет производиться сортировка;
value – некоторое числовое значение.
Заполним нашу таблицу тестовыми данными:
Примеры замены некоторых аналитических функций.
1) ROW_NUMBER() OVER(ORDER BY order_id)
2) ROW_NUMBER() OVER(PARTITION BY group_id ORDER BY order_id)
3) SUM(value) OVER(PARTITION BY group_id ORDER BY order_id)
4) LAG(value) OVER(PARTITION BY group_id ORDER BY order_id)
Для LEAD всё то же самое, только нужно сменить сортировку на ORDER BY group_id, order_id DESC
Для функций COUNT, MIN, MAX всё несколько сложнее, поскольку, пока мы не проанализируем все строчки в группе(окне), мы не сможем узнать значение функции. MS SQL, например, для этих целей «спулит» окно (временно помещает строки окна в скрытую буферную таблицу для повторного к ним обращения), в MySQL такой возможности нет. Но мы можем для каждого окна вычислить значение функции в последней строке при заданной сортировке (т.е. после анализа всего окна), а затем, отсортировав строки в окне в обратном порядке, проставить вычисленное значение по всему окну.
Таким образом, нам понадобится две сортировки. Чтобы итоговая сортировка осталась той же, что и в примерах выше, отсортируем сначала по полям group_id ASC, order_id DESC, затем по полям group_id ASC, order_id ASC.
5) COUNT(*) OVER(PARTITION BY group_id)
В первой сортировке мы просто нумеруем записи. Во второй всем строкам окна присваиваем максимальный номер, который и будет соответствовать количеству строк в окне.
Функции MAX и MIN вычисляются по аналогии. Приведу только пример для MAX:
6) MAX(value) OVER(PARTITION BY group_id)
7) COUNT(DISTINCT value) OVER(PARTITION BY group_id)
Интересная вещь, которая отсутствует в MS SQL Server, но её можно вычислить с подзапросом, взяв MAX от RANK. Так же поступим и здесь. В первой сортировке вычислим RANK() OVER(PARTITION BY group_id ORDER BY value DESC), затем во второй сортировке проставим максимальное значение всем строкам в каждом окне:
Агрегатные функции
Часто при работе с данными не нужно просматривать сами данные, а нужна информация о них. Синтаксис SQL включает в себя ряд функций, которые позволяют интерпретировать или выполнять вычисления на ваших данных через запрос SELECT. Такие функции называются агрегатными.
Функция COUNT считает и возвращает количество строк, соответствующих определенным критериям. Например, если вы хотите узнать, сколько ваших друзей предпочитают тофу, вы можете выполнить этот запрос:
Функция AVG возвращает среднее значение столбца. Например, вы можете найти средний лучший результат в турнире с помощью этого запроса:
SUM может найти общую сумму значений столбца. Например, если вы хотите посмотреть, сколько турниров вы провели за эти годы, вы можете выполнить этот запрос:
Обратите внимание, функции AVG и SUM работают правильно только с числовыми данными. Если вы попытаетесь использовать их для нечисловых данных, это приведет к ошибке или к 0, в зависимости от того, какую СУБД вы используете
MIN используется для поиска наименьшего значения в указанном столбце. Попробуйте использовать этот запрос, чтобы узнать наименьшее количество очков победителя в турнире за все годы:
Точно так же используется MAX – только эта функция ищет наибольшее числовое значение в данном столбце. Следующий запрос покажет лучший результат в турнирах за все годы:
В отличие от SUM и AVG, функции MIN и MAX могут использоваться как для числовых, так и для буквенных типов данных. При запуске в столбце со строковыми значениями функция MIN отображает первое значение в алфавитном порядке:
Аналогично MAX покажет последнее значение в алфавитном порядке:
Агрегатные функции широко применяются в СУБД. Они особенно полезны в выражениях GROUP BY, которые мы рассмотрим в следующем разделе вместе с несколькими другими операторами сортировки наборов результатов.
Select Data With PDO (+ Prepared Statements)
The following example uses prepared statements.
It selects the id, firstname and lastname columns from the MyGuests table
where the lastname is «Doe», and
displays it in an HTML table:
Example (PDO)
<?phpecho «<table style=’border: solid 1px black;’>»;
echo «<tr><th>Id</th><th>Firstname</th><th>Lastname</th></tr>»;class TableRows extends RecursiveIteratorIterator {
function __construct($it) { parent::__construct($it, self::LEAVES_ONLY);
} function current() { return «<td style=’width:150px;border:1px solid black;’>» . parent::current(). «</td>»;
} function beginChildren() { echo «<tr>»;
} function endChildren() { echo «</tr>» . «\n»;
} } $servername = «localhost»;
$username = «username»;$password = «password»;$dbname = «myDBPDO»;
try { $conn = new PDO(«mysql:host=$servername;dbname=$dbname», $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->prepare(«SELECT id, firstname, lastname FROM MyGuests
WHERE lastname=’Doe'»); $stmt->execute(); // set the resulting array to associative $result = $stmt->setFetchMode(PDO::FETCH_ASSOC); foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) {
echo $v; }}catch(PDOException $e) { echo «Error: » . $e->getMessage();}$conn = null;echo «</table>»;?>
Проверка наличия совпадения
Регулярные выражения используются для описания текста, который требуется найти в строке (и возможно, подвергнуть дополнительной обработке). Давайте вернемся к примеру, который приводился ранее в этом блоге:
DECLARE names VARCHAR2(60) := 'Anna,Matt,Joe,Nathan,Andrew,Aaron,Jeff';
Допустим, мы хотим определить на программном уровне, содержит ли строка список имен, разделенных запятыми. Для этого мы воспользуемся функцией , обнаруживающей совпадения шаблона в строке:
DECLARE names VARCHAR2(60) := 'Anna,Matt,Joe,Nathan,Andrew,Jeff,Aaron'; names_adjusted VARCHAR2(61); comma_delimited BOOLEAN; BEGIN --Поиск по шаблону comma_delimited := REGEXP_LIKE(names,'^(*,)+(*){1}$'); --Вывод результата DBMS_OUTPUT.PUT_LINE( CASE comma_delimited WHEN true THEN 'Обнаружен список с разделителями!' ELSE 'Совпадение отсутствует.' END); END;
Результат:
Обнаружен список с разделителями
Чтобы разобраться в происходящем, необходимо начать с выражения, описывающего искомый текст. Общий синтаксис функции выглядит так:
REGEXP_LIKE (исходная_строка, шаблон )
Здесь — символьная строка, в которой ищутся совпадения; шаблон — регулярное выражение, совпадения которого ищутся в исходной_строке; модификаторы — один или несколько модификаторов, управляющих процессом поиска. Если функция находит совпадение шаблона в , она возвращает логическое значение ; в противном случае возвращается .
Процесс построения регулярного выражения выглядел примерно так:
- Каждый элемент списка имен может состоять только из букв и пробелов. Квадратные скобки определяют набор символов, которые могут входить в совпадение. Диапазон a–z описывает все буквы нижнего регистра, а диапазон A–Z — все буквы верхнего регистра. Пробел находится между двумя компонентами выражения. Таким образом, этот шаблон описывает один любой символ нижнего или верхнего регистра или пробел.
- * Звездочка является квантификатором — служебным символом, который указывает, что каждый элемент списка содержит ноль или более повторений совпадения, описанного шаблоном в квадратных скобках.
- *, Каждый элемент списка должен завершаться запятой. Последний элемент является исключением, но пока мы не будем обращать внимания на эту подробность.
- *,) Круглые скобки определяют подвыражение, которое описывает некоторое количество символов, завершаемых запятой. Мы определяем это подвыражение, потому что оно должно повторяться при поиске.
- ]*,)+ Знак + — еще один квантификатор, применяемый к предшествующему элементу (то есть к подвыражению в круглых скобках). В отличие от * знак + означает «одно или более повторений». Список, разделенный запятыми, состоит из одного или нескольких повторений подвыражения.
- ( В шаблон добавляется еще одно подвыражение: (*). Оно почти совпадает с первым, но не содержит запятой. Последний элемент списка не завершается запятой.
- Мы добавляем квантификатор {1}, чтобы разрешить вхождение ровно одного элемента списка без завершающей запятой.
- ^ Наконец, метасимволы ^ и привязывают потенциальное совпадение к началу и концу целевой строки. Это означает, что совпадением шаблона может быть только вся строка вместо некоторого подмножества ее символов.
Функция анализирует список имен и проверяет, соответствует ли он шаблону. Эта функция оптимизирована для простого обнаружения совпадения шаблона в строке, но другие функции способны на большее!