Упрощение создания таблиц для записи в них данных из SQL запросов

В одном из фильмов с Уиллом Смитом главный герой в процессе обзвона клиентов заметил, что если он не кладет трубку, а сразу набирает следующий номер, то на один звонок он тратит меньше времени и в день может совершить больше звонков. Таким образом, он сократил время на мелких рутинных делах. Подобное возможно и в других сферах деятельности. Например, если работа связана с выгрузкой или загрузкой данных на SQL Server.

При написании больших запросов зачастую требуется записать в «физическую» таблицу результаты соединения нескольких таблиц. Конечно, сделать это можно (или даже нужно) традиционным способом с применением инструкции create TABLE, но для этого необходимо заранее знать все типы данных в столбцах, прописывать их наименования, что занимает определённое время. Более того, в силу человеческого фактора не исключён риск совершения ошибок, которые приведут к лишним трудозатратам на пересоздание таблицы и потере времени при выполнении запроса.

Кто-то скажет: «А как же инструкция select INTO?». Да, эта инструкция позволяет сразу из запроса создать новую таблицу и записать туда результаты запроса выборки, но есть один большой очень критичный недостаток. На больших объёмах данных запросы, содержащие данную инструкцию занимают значительное количество ресурсов на сервере и блокируют работу других пользователей сервера. Обычно такие запросы отключаются администраторами серверов, а в некоторых случаях ещё и блокируются учётные записи пользователей, злоупотребляющих такими выгрузками.

В качестве решения вопроса можно применить следующий вариант. Учитывая, что инструкция select INTO копирует структуру результирующей таблицы, можно применить её к запросу, но не нагружая сервер, выбирать 0 строк (Select top 0 * into и т.д.). После этого, выполнить обычный запрос insert INTO во вновь созданную таблицу. Для того чтобы не делать это каждый раз (ведь главная цель – экономия времени), оформляем всё это в хранимую процедуру с использованием инструкции IF EXIST и данных из системных таблиц.

Таким образом, получаем следующий код:

create procedure [dbo].[sp_ctwsi] (@tablename nvarchar(max), @sql nvarchar(max)) as begin if not exists ( select s.name shm, o.name tbl from sys.objects o inner join sys.schemas s on o.schema_id = s.schema_id where type = 'u' and o.name = substring(@tablename, CHARINDEX('.', @tablename)+1, len(@tablename) - CHARINDEX('.', '')+1) and s.name = substring(@tablename, 1, CHARINDEX('.', @tablename)-1) ) begin exec ('select top 0 * into '+@tablename+' from (' + @sql +') t' ) end else begin exec ('insert into '+@tablename+' select * from (' + @sql +') t' ) end end

Как видно из кода, на входе в процедуру требуется передать два параметра – наименование таблицы со схемой через точку (например, «dbo.MyTable») и SQL-запрос, результаты которого требуется записать в таблицу.

Вот так можно один раз потратить немного времени на написание процедуры и избавиться от мелких, но рутинных задач в дальнейшем. И это только один из вариантов, ведь у каждого программиста наверняка может найтись свой алгоритм оптимизации повседневных задач.

22
6 комментариев

а не возникает вопроса - нафига пользователю разрешать создавать левую таблицу в sql -сервере?

1
Автор

В каждой организации могут происходить различные процессы по работе с данными, разные условия выполнения задач, где "книжные" классические методы ведения баз данных не работают. Например, когда пользователи самостоятельно анализируют данные и у них своя "песочница", где они создают таблицы, делают выборки и впоследствии удаляют за ненадобностью.

А то что если в первых тысячах строк будет   varchar(20) а в следующих varchar (50) и произойдет усечение строк, никто не подумал? 

1

Причём тут первая тысяча, если таблица создаётся по select top 0?

Автор

Все столбцы таблицы, указанной в аргументе new_table, получают такие же имена, значения, типы данных и свойства допустимости значений NULL, которые указаны в соответствующем выражении в списке выбора.
Собственно, это одно из преимуществ использования инструкции: https://docs.microsorft.com/ru-ru/sql/t-sql/queries/select-into-clause-transact-sql?view=sql-server-ver15

Китайская BYD представила платформу для запуска дронов DJI с крыши автомобиля

Она доступна в Китае по цене около $2200.

Источник: Handout / SCMP
55
11
реклама
разместить
На двух станциях метро в Санкт-Петербурге запустили оплату проезда «лицом»

Чтобы воспользоваться этим методом, нужно зарегистрироваться в системе и привязать биометрию к банковской карте.

Источник: Комитет по транспорту Санкт-Петербурга / «Фонтанка»
77
22
11
«Вы — супергерой?» «Нет, обычный профессионал». Разбираемся, зачем в бухгалтерии бизнес-ассистент
«Вы — супергерой?» «Нет, обычный профессионал». Разбираемся, зачем в бухгалтерии бизнес-ассистент

Представьте, что вы доверили на аутсорсинг свою бухгалтерию. Кажется, что вот теперь наступит покой, но.. Как бы не так. Вы не успели утренний кофе налить, а от бухгалтера — миллион сообщений с вопросами и пара пропущенных. Где обещанное свободное время на личные дела? У нас всё работает не так! Вот почему⬇

88
Госдума поддержала в первом чтении законопроект о штрафах до 500 тысяч рублей за продажу энергетиков детям

С 1 марта 2025 года продавать энергетики несовершеннолетним запрещено по всей России.

77
33
Apple представила iPad Air с чипом M3 и базовый iPad с чипом A16

А также обновлённую клавиатуру Magic Keyboard с трекпадом для iPad Air.

Источник здесь и далее — Apple 
1313
99
11
11
GPT-4.5 — модель с «эмоциональным интеллектом» и «человечными» ответами: отзывы и критика

Собрали комментарии разработчиков, примеры использования и тесты.

44
11
В Якутии определили победителей регионального этапа Всероссийского конкурса «Моя профессия – ИТ»
Фото: Саргына Скрябина, ЯСИА
Правительство не продлило мораторий на выездные налоговые проверки ИТ-компаний

Его действие завершилось 3 марта 2025 года.

Фото РБК
1212
99
11
Тупняк конечно феерический. Какой нахрен мараторий? Есть подозрение что чтото в компании не чисто - проверяй, нет подозрений, не мешай работать.
[]