Задача: как получить список ID измененных записей в запросе UPDATE в переменную-коллекцию v_ids?
Таблица table1 состоит из трех колонок ID (PK), COL1, COL2).
Полный код PL/SQL-блока в посте вторника.
Принцип решения:
Команда DML UPDATE имеет дополнительную возможность по возврату полей обновленных записей.
Нам в помощь, конструкция returning … into.
Довольно часто применяется на практике.
Подход с дополнительным запросом на select не применим по разным причинам.
PL/SQL-код:
/
Надеюсь, вам понравилась задачка 😉
#sql #plsql #задача #bulkcollect #returning
Таблица table1 состоит из трех колонок ID (PK), COL1, COL2).
Полный код PL/SQL-блока в посте вторника.
Принцип решения:
Команда DML UPDATE имеет дополнительную возможность по возврату полей обновленных записей.
Нам в помощь, конструкция returning … into.
Довольно часто применяется на практике.
Подход с дополнительным запросом на select не применим по разным причинам.
PL/SQL-код:
declare
type t_ids is table of table1.id%type;
v_ids t_ids;
begin
update table1
set col1 = 2
where col2 = 'xxx'
returning id bulk collect into v_ids;
end;
/
Надеюсь, вам понравилась задачка 😉
#sql #plsql #задача #bulkcollect #returning
🔥1
Транзакции и кислотность
Очень часто на собеседованиях можно встретить вопросы: что такое транзакция? что такое кислотность транзакций?
Транзакция - перевод БД из одного согласованного состояние в другое.
На прикладном уровне: фиксация или откат группы операций.
Кислотность (ACID) - требования к транзакционной СУБД. Их четыре:
Atomicity (Атомарность) - никакая транзакция в системе не будет зафиксирована частично.
Consistency (Согласованность) - каждая успешная транзакция фиксирует только допустимые результаты.
Isolation (Изолированность) - во время выполнения транзакции, параллельные транзакции не должны оказывать влияние на её результат.
Durability (Долговечность) - изменения в данных являются постоянными.
Это базовые понятия, которые должны быть понятны, любому разработчику, сталкивающемуся с реляционными СУБД.
#теория #собеседование #транзакции
Очень часто на собеседованиях можно встретить вопросы: что такое транзакция? что такое кислотность транзакций?
Транзакция - перевод БД из одного согласованного состояние в другое.
На прикладном уровне: фиксация или откат группы операций.
Кислотность (ACID) - требования к транзакционной СУБД. Их четыре:
Atomicity (Атомарность) - никакая транзакция в системе не будет зафиксирована частично.
Consistency (Согласованность) - каждая успешная транзакция фиксирует только допустимые результаты.
Isolation (Изолированность) - во время выполнения транзакции, параллельные транзакции не должны оказывать влияние на её результат.
Durability (Долговечность) - изменения в данных являются постоянными.
Это базовые понятия, которые должны быть понятны, любому разработчику, сталкивающемуся с реляционными СУБД.
#теория #собеседование #транзакции
👍3
Уровни изоляции транзакций
Стандарт SQL определяет четыре уровня изоляции: чем строже уровень, тем меньше влияния оказывают параллельно работающие транзакции друг на друга.
1. DIRTY READ или READ UNCOMMITED - сессия, может читать данные грязные/не зафиксированные другой сессии.
2. READ COMMITED - сессия, видит только зафиксированные данные других сессий. Увидит как новые строки, так и изменения в существующих.
3. REPEATABLE READ - сессия, видит только зафиксированные данные других сессий. Увидит только новые строки, изменения внутри строк - нет.
4. SERIALIZABLE - полностью изолированная среда. Не увидит, вообще никаких изменений других сессий.
В Oracle используется только READ COMMITED (по умолчанию) и SERIALIZABLE (через команду set transaction).
На практике, SERIALIZABLE используется крайне редко.
Достаточно, частный вопрос на собеседованиях: какие уровни изоляции транзакций вы знаете?
#теория #собеседование #транзакции
Стандарт SQL определяет четыре уровня изоляции: чем строже уровень, тем меньше влияния оказывают параллельно работающие транзакции друг на друга.
1. DIRTY READ или READ UNCOMMITED - сессия, может читать данные грязные/не зафиксированные другой сессии.
2. READ COMMITED - сессия, видит только зафиксированные данные других сессий. Увидит как новые строки, так и изменения в существующих.
3. REPEATABLE READ - сессия, видит только зафиксированные данные других сессий. Увидит только новые строки, изменения внутри строк - нет.
4. SERIALIZABLE - полностью изолированная среда. Не увидит, вообще никаких изменений других сессий.
В Oracle используется только READ COMMITED (по умолчанию) и SERIALIZABLE (через команду set transaction).
На практике, SERIALIZABLE используется крайне редко.
Достаточно, частный вопрос на собеседованиях: какие уровни изоляции транзакций вы знаете?
#теория #собеседование #транзакции
👍3
Сегодня будет немного необычная задачка в формате голосования 👍🏻
Какое из выражений вернет числовое значение?
1. select add_months(max(hire_date),6) from emp;
2. select round(hire_date) from emp;
3. select sysdate – hire_date from emp;
4. select to_number(hire_date+7) from emp;
Рекомендую попытаться ответить без выполнения в СУБД.
Смотрите объяснения в посте в четверг 🎓
Перезалил с удобным форматированием.
#sql #задача
Какое из выражений вернет числовое значение?
1. select add_months(max(hire_date),6) from emp;
2. select round(hire_date) from emp;
3. select sysdate – hire_date from emp;
4. select to_number(hire_date+7) from emp;
Рекомендую попытаться ответить без выполнения в СУБД.
Смотрите объяснения в посте в четверг 🎓
Перезалил с удобным форматированием.
#sql #задача
👍1
Unit-тестирование в СУБД Oracle
Всем привет!
Наконец-то, свершилось 🙂
Я записал видео про Unit-тестирование в СУБД Oracle 🔥
В нем, я расскажу, что такое Unit-тестирование на уровне СУБД, какой фреймворк использовать, рассмотрим примеры.
Материал будет полезен всем кто хочет повысить уровень надежности приложений в СУБД Oracle.
Ни в коем случае, не стоит думать, что тестирование это про тестировщиков и вас как разработчиков это не касается. Это не так. Тестирование кода, написание тестов говорит о высокой инженерной культуре. И нам как разработчикам, просто необходимо писать тесты на наш код.
Приятного просмотра!
🎥 Смотреть видео - 16 мин
#видео #utplsql #тестирование
Всем привет!
Наконец-то, свершилось 🙂
Я записал видео про Unit-тестирование в СУБД Oracle 🔥
В нем, я расскажу, что такое Unit-тестирование на уровне СУБД, какой фреймворк использовать, рассмотрим примеры.
Материал будет полезен всем кто хочет повысить уровень надежности приложений в СУБД Oracle.
Ни в коем случае, не стоит думать, что тестирование это про тестировщиков и вас как разработчиков это не касается. Это не так. Тестирование кода, написание тестов говорит о высокой инженерной культуре. И нам как разработчикам, просто необходимо писать тесты на наш код.
Приятного просмотра!
🎥 Смотреть видео - 16 мин
#видео #utplsql #тестирование
YouTube
Oracle Unit-тестирование за 16 минут
В этом видео, я расскажу что такое Unit-тестирование на уровне СУБД, как воспользоваться фреймворком для тестирования, рассмотрим примеры.
Материал будет полезен всем кто хочет повысить уровень надежности приложений в СУБД Oracle.
https://github.com/kiv…
Материал будет полезен всем кто хочет повысить уровень надежности приложений в СУБД Oracle.
https://github.com/kiv…
👍1
Задача: Какое из выражений вернет числовое значение?
Решение:
Разберем каждый пункт.
1)
2)
3)
4)
Итого: правильный ответ- пункт 3.
⚠️Разница между timestamp - интервал.
#sql #решениезадачи #date
Решение:
Разберем каждый пункт.
1)
select add_months(MAX(hire_date),6) from emp;
Берем максимальную дату в таблице (max) и прибавляем 6 месяцев (add_months). Результат - тип date.2)
select round(hire_date) from emp;
На практике, функция round (округление) не применяется к датам. Однако, ошибки не будет. Значение hire_date будет округлено либо в меньшую сторону (если время до обеда), либо в большую сторону (если время после обеда). Результат - тип date.3)
select sysdate – hire_date from emp;
Арифметика дат. Разница между датами (тип date) - это количество дней. Результат - тип number.4)
select to_number(hire_date+7) from emp;
+7 к date мы сделать сможем, это будет +7 дней. Но вот применить функцию to_number нельзя. Даты в Oracle хранятся в своем внутреннем формате, это не Unix timestamp с секундами от 1970 года. Результат - исключение.Итого: правильный ответ- пункт 3.
⚠️Разница между timestamp - интервал.
#sql #решениезадачи #date
❤1
You Asked
Как получить DDL скрипт партиционированной таблицы и индексов в Oracle?
and we said...
Используйте IDE, например, SQL Developer.
Или функцию dbms_metadata.get_ddl.
Например:
#asktom #dbms_metadata
Как получить DDL скрипт партиционированной таблицы и индексов в Oracle?
and we said...
Используйте IDE, например, SQL Developer.
Или функцию dbms_metadata.get_ddl.
Например:
select dbms_metadata.get_ddl(object_type => 'TABLE', name => 'MYTAB') ddlПодробности в статье Тома
from dual;
#asktom #dbms_metadata
👍1
Оптимизация - процесс, направленный на уменьшение времени отклика, снижение трат ресурсов, возможность увеличить количество параллельных сессий, при тех же ресурсах и др.
Когда говорят об оптимизации, во многих головах, всплывают только запросы и их изменение.
Но это далеко не так.
Перечислю, лишь, наиболее крупные области:
1. Настройка сервера.
2. Настройка СУБД.
3. Алгоритмическая оптимизация приложения.
4. Выбор структур хранения данных.
5. Оптимизация PL/SQL-кода.
6. Оптимизация SQL-запросов.
Если первые два пункта прерогатива - администраторов (DBA), то за остальные пункты отвечаем мы - разработчики (DBD).
Области настолько огромные и сложные, что может потребовать не один год, чтобы хоть как-то приблизиться к их пониманию. Никогда не будет момента, когда можно будет сказать “вот теперь я знаю всё про оптимизацию”.
Некоторые темы я затрону в нашем телеграм-канале. В будущем, я планирую сделать обучающий курс по оптимизации, где будут даны направления и инструменты, поделюсь опытом.
#оптимизация
Когда говорят об оптимизации, во многих головах, всплывают только запросы и их изменение.
Но это далеко не так.
Перечислю, лишь, наиболее крупные области:
1. Настройка сервера.
2. Настройка СУБД.
3. Алгоритмическая оптимизация приложения.
4. Выбор структур хранения данных.
5. Оптимизация PL/SQL-кода.
6. Оптимизация SQL-запросов.
Если первые два пункта прерогатива - администраторов (DBA), то за остальные пункты отвечаем мы - разработчики (DBD).
Области настолько огромные и сложные, что может потребовать не один год, чтобы хоть как-то приблизиться к их пониманию. Никогда не будет момента, когда можно будет сказать “вот теперь я знаю всё про оптимизацию”.
Некоторые темы я затрону в нашем телеграм-канале. В будущем, я планирую сделать обучающий курс по оптимизации, где будут даны направления и инструменты, поделюсь опытом.
#оптимизация
🤯1
Небольшое голосование ✅
Хотели бы пройти курс по оптимизации?
- поиск проблем (AWR, ASH, профайлейры и др.);
- основы оптимизации запросов;
- основы оптимизации PL/SQL кода;
- алгоритмическая оптимизация;
- другие темы.
теория + практика, домашние задания 🎓
Палец вверх, если "Да" 👍🏻
Хотели бы пройти курс по оптимизации?
- поиск проблем (AWR, ASH, профайлейры и др.);
- основы оптимизации запросов;
- основы оптимизации PL/SQL кода;
- алгоритмическая оптимизация;
- другие темы.
теория + практика, домашние задания 🎓
Палец вверх, если "Да" 👍🏻
🤯1
Задача: необходимо написать запрос, без применения PL/SQL, получающий из строки типа “str1;str2;str3” (разделитель “;”) 3 строки результата - str1, str2, str3.
Значений перечисленных через ";" может быть любое количество. Нельзя затачиваться на количество строк = 3.
Необходимый результат:
str1
str2
str3
Смотрите решение в посте в четверг 🎓
#sql #задача
Значений перечисленных через ";" может быть любое количество. Нельзя затачиваться на количество строк = 3.
Необходимый результат:
str1
str2
str3
Смотрите решение в посте в четверг 🎓
#sql #задача
🔥1
Виды соединения таблиц
Представьте запрос типа:
Существуют три основных типа соединения:
1. Nested loops (цикл в цикле).
2. Merge join (соединение слиянием).
3. Hash join (hash-соединение).
Каждый тип соединения подходит для своих ситуаций. Зависит от структур данных, количества выбираемых данных и других факторов.
Чаще всего, особенно в OLTP-системах, подходит nested-loops.
СУБД выбираем автоматически какой тип соединения применить. Иногда оптимизатор ошибается. При помощи хинтов, мы можем подсказать, какой тип выбрать.
Важно не путать соединение на логическом уровне (left join, cross join, join и др.) c физическим уровнем.
В следующем посте, расскажу про соединение через nested loops.
#оптимизация #nestedloops #hashjoin #mergejoin
Представьте запрос типа:
select *Задумывались ли вы, как СУБД будет их соединять?
from T1
join T2 on T2.t1_id = T1.id;
Существуют три основных типа соединения:
1. Nested loops (цикл в цикле).
2. Merge join (соединение слиянием).
3. Hash join (hash-соединение).
Каждый тип соединения подходит для своих ситуаций. Зависит от структур данных, количества выбираемых данных и других факторов.
Чаще всего, особенно в OLTP-системах, подходит nested-loops.
СУБД выбираем автоматически какой тип соединения применить. Иногда оптимизатор ошибается. При помощи хинтов, мы можем подсказать, какой тип выбрать.
Важно не путать соединение на логическом уровне (left join, cross join, join и др.) c физическим уровнем.
В следующем посте, расскажу про соединение через nested loops.
#оптимизация #nestedloops #hashjoin #mergejoin
👍2
Задача: необходимо написать запрос, без применения PL/SQL, получающий из строки типа “str1;str2;str3” (разделитель “;”) 3 строки результата - str1, str2, str3.
Значений перечисленных через разделитель может быть любое количество. Нельзя затачиваться на количество строк = 3.
Принцип решения:
Применяем возможности иерархических запросов и регулярок.
* instr(str, ';', 1, level - 1) > 0 - находит вхождение разделителя и генерит след уровень
* regexp_substr(str, '[^;]+', 1, level) - получает вхождение на текущем уровне.
Если добавить вторым столбцом level (уровень иерархии), станет более понятней.
Запрос:
Надеюсь, вам понравилась задачка 😉
#sql #решениезадачи
Значений перечисленных через разделитель может быть любое количество. Нельзя затачиваться на количество строк = 3.
Принцип решения:
Применяем возможности иерархических запросов и регулярок.
* instr(str, ';', 1, level - 1) > 0 - находит вхождение разделителя и генерит след уровень
* regexp_substr(str, '[^;]+', 1, level) - получает вхождение на текущем уровне.
Если добавить вторым столбцом level (уровень иерархии), станет более понятней.
Запрос:
select regexp_substr(str, '[^;]+', 1, level) str
from (select 'str1;str2;str3' str from dual) t
connect by instr(str, ';', 1, level - 1) > 0;
Надеюсь, вам понравилась задачка 😉
#sql #решениезадачи
👍4
Алгоритм соединения вложенными циклами (Nested loops join) — разновидность алгоритма соединения.
В общем случае, алгоритм получает на вход n таблиц и условия соединения. Результатом его работы является набор строк с результатами соединения.
Упрощая до двух таблиц, алгоритм можно описать следующим образом: для каждой строки одной из таблиц (ведущей) выполняется поиск в другой таблице (ведомой) строк, соответствующих условию соединения.
Псевдокод работы:
В плане запроса выглядит как показано на скриншоте. Шаг соединения двух таблиц - NESTED LOOPS.
В следующем посте расскажу когда и где применять.
#оптимизация #nestedloops
В общем случае, алгоритм получает на вход n таблиц и условия соединения. Результатом его работы является набор строк с результатами соединения.
Упрощая до двух таблиц, алгоритм можно описать следующим образом: для каждой строки одной из таблиц (ведущей) выполняется поиск в другой таблице (ведомой) строк, соответствующих условию соединения.
Псевдокод работы:
Для каждой строки [r] из [Ведущая таблица]Крайне желательно, чтобы у ведомой таблицы был индекс на поля соединения. Привет индексам на foreign key.
Для каждой строки [s] из [Ведомая таблица]
Если УдовлетворяетУсловию ([r],[s],[Условие соединения])
Вывести ([r],[s]);
В плане запроса выглядит как показано на скриншоте. Шаг соединения двух таблиц - NESTED LOOPS.
В следующем посте расскажу когда и где применять.
#оптимизация #nestedloops
❤2
Когда использовать Nested loops?
Как вы уже поняли из предыдущего поста данный метод проще всего представить в виду двух циклов: первый - верхний, второй - вложенный.
Соответственно, чем меньше итераций на каждом из циклов тем лучше.
Крайне желательно, чтобы выбирался незначительный объем как из первой так и из второй таблиц. На первое место ставят таблицу с низким количеством записей удовлетворяющим условиям в where, и дальше от неё пляшут.
Идеальный случай:
1. В первую таблицу заходим по PK или низкоселективному индексу.
2. Во вторую таблицу заходим по низкоселективному индексу.
По поводу индекса во второй таблице, скорее всего, это будет индекс на поля связки с master-таблицей. Это одна из причин, почему на FK делают индексы.
Речь шла про оперативные таблицы, а не справочники с малым количеством записей.
#оптимизация #nestedloops
Как вы уже поняли из предыдущего поста данный метод проще всего представить в виду двух циклов: первый - верхний, второй - вложенный.
Соответственно, чем меньше итераций на каждом из циклов тем лучше.
Крайне желательно, чтобы выбирался незначительный объем как из первой так и из второй таблиц. На первое место ставят таблицу с низким количеством записей удовлетворяющим условиям в where, и дальше от неё пляшут.
Идеальный случай:
1. В первую таблицу заходим по PK или низкоселективному индексу.
2. Во вторую таблицу заходим по низкоселективному индексу.
По поводу индекса во второй таблице, скорее всего, это будет индекс на поля связки с master-таблицей. Это одна из причин, почему на FK делают индексы.
Речь шла про оперативные таблицы, а не справочники с малым количеством записей.
#оптимизация #nestedloops
👍1
Пример:
Есть клиент, у него есть банковские счета.
Таблица клиентов - 10М, банковских счетов - 100М.
Мы знаем PK клиента, нам нужно вернуть информацию по клиенту и всю информацию по банковским счетам.
Nested loops подходит идеально для этого случая. Для первого цикла будет выбрана одна запись (PK), для второго цикла от силы до 10 записей.
Есть клиент, у него есть банковские счета.
Таблица клиентов - 10М, банковских счетов - 100М.
Мы знаем PK клиента, нам нужно вернуть информацию по клиенту и всю информацию по банковским счетам.
Nested loops подходит идеально для этого случая. Для первого цикла будет выбрана одна запись (PK), для второго цикла от силы до 10 записей.
select cl.*, ba.*#оптимизация #nestedloops
from client cl
join bank_account ba on ba.cl_id = cl.cl_id
where cl.cl_id = … ;
❤1
Nested loops, коллекции и хинты
Довольно часто коллекции используются как источник данных.
Например:
На каком-то из предыдущих шагов нашей программы мы наполнили коллекцию. Значения в ней это number. ID наших клиентов. По этим клиентам мы должны получить информацию по банковским счетам. И что-то сделать с результатом.
Код:
Смотрим предполагаемый план выполнения запроса. Он в заголовке.
Oracle предлагает соединять таблицы через hash_join. В run-time план может поменяться, но тем не менее почему так получилось?
#оптимизация #nestedloops #hints
Довольно часто коллекции используются как источник данных.
Например:
На каком-то из предыдущих шагов нашей программы мы наполнили коллекцию. Значения в ней это number. ID наших клиентов. По этим клиентам мы должны получить информацию по банковским счетам. И что-то сделать с результатом.
Код:
create or replace type t_numbers is table of number(30);Идеальный вариант для nested loops. На первой итерации всего три строки. Вторая итерация, так же отберет небольшое количество (до 10 счетов на одного клиента).
/
declare
v_ids t_numbers := t_numbers(10, 999, 7777);
begin
for i in (select *
from table(v_ids) t
join bank_account ba on ba.cl_id = value(t)) loop
-- что-то делаем
end loop;
end;
/
Смотрим предполагаемый план выполнения запроса. Он в заголовке.
Oracle предлагает соединять таблицы через hash_join. В run-time план может поменяться, но тем не менее почему так получилось?
#оптимизация #nestedloops #hints
🤯1
Потому что Oracle заранее не знает, какое количество элементов\строк будет в коллекции.
1. Если мы знаем хотя бы порядок, можно использовать хинт cardinality.
2. Далее, мы понимаем, что эта коллекция должна идти первой в соединении - используем хинт leading.
3. И наконец, понимая, что nested loops будет лучшим решением в данной ситуации задаем хинт use_nl.
Таким образом, мы жестко забиваем гвоздями план выполнения.
Итоговый запрос:
Не везде и всегда это подходит, поэтому я утверждаю, что оптимизация довольно сложный процесс.
Пожалуй, на этом примере, я пока остановлю свои посты про оптимизацию SQL-запросов. В следующих про PL/SQL 😉
#оптимизация #nestedloops #hints
1. Если мы знаем хотя бы порядок, можно использовать хинт cardinality.
2. Далее, мы понимаем, что эта коллекция должна идти первой в соединении - используем хинт leading.
3. И наконец, понимая, что nested loops будет лучшим решением в данной ситуации задаем хинт use_nl.
Таким образом, мы жестко забиваем гвоздями план выполнения.
Итоговый запрос:
select /*+ cardinality(t 10) use_nl(t ba) leading(t ba) */План в заголовке.
*
from table(t_numbers(:v_ids)) t
join bank_account ba on ba.cl_id = value(t);
Не везде и всегда это подходит, поэтому я утверждаю, что оптимизация довольно сложный процесс.
Пожалуй, на этом примере, я пока остановлю свои посты про оптимизацию SQL-запросов. В следующих про PL/SQL 😉
#оптимизация #nestedloops #hints
🤯1
Задача: требуется из строки, содержащей цифры, удалить все цифры.
Например строка: 'Приветствую363283 тебя3434!'
Требуемый результат: ‘Приветствую тебя!’
Решение:
1) Используем функцию translate и её особенность (см. документацию).
Надеюсь, вам понравилась задачка 😉
#sql #решениезадачи
Например строка: 'Приветствую363283 тебя3434!'
Требуемый результат: ‘Приветствую тебя!’
Решение:
1) Используем функцию translate и её особенность (см. документацию).
select translate('Приветствую363283 тебя3434!',2) Используем функцию regexp_replace с соответствующим шаблоном.
'x0123456789',
'x') res
from dual;
select regexp_replace('Приветствую363283 тебя3434!',
'[[:digit:]]+',
'') res
from dual;
Надеюсь, вам понравилась задачка 😉
#sql #решениезадачи
🔥1