Сообщения

Показаны сообщения с ярлыком "SQL"

Рекурсивные SQL запросы

Изображение
CTE(обобщенное табличное выражение) может ссылаться на себя, создавая рекурсивное CTE. Рекурсивное CTE многократно выполняется, чтобы возвращать подмножество данных до тех пор, пока не получится конечный результирующий набор. Обычно рекурсивные запросы используются для возвращения иерархических данных, например: отображение сотрудников в структуре организации или генерация последовательности. Структура рекурсивного CTE WITH cte_name ( column_name [,...n] ) AS ( CTE_query_definition –- Anchor member is defined. UNION ALL CTE_query_definition –- Recursive member is defined referencing cte_name. ) -- Statement using the CTE SELECT * FROM cte_name CTE разбивается на закрепленный и рекурсивный элементы. Запускается закрепленный элемент с созданием первого вызова. Рекурсивный элемент ссылается на закрепленный и вызывается пока не вернет пустой набор. Классический пример с сотрудниками DECLARE @Employees TABLE ( ID int NOT NULL, [Name] nvarchar(200) NOT NULL, Manag...

Кратко про SQLAlchemy Core

SQLAlchemy Engine это слой абстракции над DB-API. Он содержит DB-API драйвера для разных СУБД, их можно указать в строке подключения. Engine.execute() и Engine.connect() два основных метода. Так же у него есть свой пул соединений. create_engine() - фабричная функция для создания Engine. Metadata это логическая структура базы данных. Она содержит список таблиц(Table), их отношения и другие объекты. Table абстракция таблицы. Содержит колонки(Column) и другие свойства. Таким образом можно иметь одновременно несколько engine с разными драйверами и коннектами, разные metadata, и совместно их использовать. примеры на github from sqlalchemy import MetaData, Table , Column , Integer , Numeric , String, DateTime from datetime import datetime metadata = MetaData() users = Table ( 'users' , metadata, Column ( 'user_id' , Integer (), primary_key = True ), Column ( 'username' , String( 15 ), nullable = False , unique = True ), ...

Асинхронное выполнение процедур или триггера в MS SQL Server

После изменений данных иногда требуется дополнительно произвести какие то действия, это может быть пересчет каких то агрегаций, отправка сообщения и пр. Процессу вносившему изменения как правило важно знать только результат транзакции и не очень интересно ожидать выполнения дополнительных операций. Асинхронный вызов можно организовать через очередь. В следующий раз напишу как это сделать через обычную таблицу и job, а сегодня о компоненте Service Broker. У Service Broker много возможностей, он позволяет взаимодействовать и между сервера, но местами не так удобен и гибок, в итоге часто эффективней выносить такую логику за СУБД. Но для простых и понятных задач вполне годная штука. 1. Создаем БД IF DB_ID (N 'DB_001' ) IS NOT NULL DROP DATABASE DB_001; GO CREATE DATABASE DB_001 2. Включаем Service Broker ALTER DATABASE [DB_001] SET ENABLE_BROKER with rollback IMMEDIATE ; 3. Создаем два типа сообщений CREATE MESSAGE TYPE [AsyncRequest] VA...

Установка PostgreSQL-9.6 и pgAdmin на Ubuntu 16.4

На данный момент из официальных репозиториев есть возможность установить postgresql-9.4 и pgadmin3. Но нам нужна актуальная стабильная версию postgresql-9.6 и pgadmin4 для нее. Перед установкой нужно проверить настройки локализации: $ locale Для корректного хранения данных на русском языке LC_CTYPE и LC_COLLATE должны иметь значения ru_RU.UTF8 При необходимости их можно установить: $ export LC_CTYPE=ru_RU.UTF8 $ export LC_COLLATE=ru_RU.UTF8 Проверяем наличие локали ru_RU.utf8 $ locale -a | grep ru_RU Если нет то добавляем: $ sudo locale-gen ru_RU.utf8 Добавляем репозиторий postgresql.org В файл  /etc/apt/sources.list или  /etc/apt/sources.list.d/pgdg.list добавляем новую строчку: deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main Загружаем и добавляем ключ: $ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \sudo apt-key add -sudo apt-get update Устанавливаем postgresql-9.6: $ sudo apt-get install po...

SARG предикаты в MS SQL Server

Довольно часто у начинающих разработчиков возникает вопрос почему оптимизатор запросов не использует поиск по нужному им индексу. Работа оптимизатора тема очень не простая и под капотом у него куча нюансов. Но есть два момента на которые стоит обратить внимания в первую очередь, это селективность и какие предикаты поиска используются. Про селективность, а конкретней про статистику в следующий раз, а сейчас немного про SARG предикаты. SARG (Seekable/Searchble Arguments) предикаты позволяют сделать поиск по индексу. Любые манипуляции над столбцами которые участвуют в поиске не позволяют использовать алгоритмы поиска по индексу. Например нужно найти данные у которых значения в столбце меньше на единицу чем аргумент: where col - 1 =@ var При таком поиске придется рассчитывать значение  col - 1  для каждой строчки и поиск по индексу использован не будет. Запрос нужно переписать так, что бы значения для предиката высчитывалось один раз и дальше использовалось для поиска...

WebRequest в MS SQL Server

Для того что бы отправлять/загружать данные по сети из MS SQL Server, можно написать две небольшие CLR функцию. Для HTTP методов POST и GET. Собираем сборку и копируем к примеру в C:\clr\SqlWebRequest.dll Дальше настраиваем MSQL Server и подключаем функции. Включаем интеграцию со средой CLR sp_configure 'clr enabled' , 1 ; RECONFIGURE; Если в сборки есть код который работает вне контекста MS Sql Server, то необходимо явно указать что БД "надежна" ALTER DATABASE myDB SET TRUSTWORTHY ON ; Так же возможно понадобится изменить владельца EXEC sp_changedbowner 'sa' Регистрируем сборку в БД CREATE ASSEMBLY SqlWebRequest FROM 'C:\clr\SqlWebRequest.dll' WITH PERMISSION_SET = UNSAFE; И создаем sql функции CREATE FUNCTION dbo.WebrequestGET( @ uri nvarchar( max ), @ user nvarchar( 255 ) = NULL , @ passwd nvarchar( 255 ) = NULL ) RETURNS nvarchar( max ) AS EXTERNAL NAME SqlWebRequest.F...