Упрощение создания таблиц для записи в них данных из SQL запросов
В одном из фильмов с Уиллом Смитом главный герой в процессе обзвона клиентов заметил, что если он не кладет трубку, а сразу набирает следующий номер, то на один звонок он тратит меньше времени и в день может совершить больше звонков. Таким образом, он сократил время на мелких рутинных делах. Подобное возможно и в других сферах деятельности. Например, если работа связана с выгрузкой или загрузкой данных на SQL Server.
При написании больших запросов зачастую требуется записать в «физическую» таблицу результаты соединения нескольких таблиц. Конечно, сделать это можно (или даже нужно) традиционным способом с применением инструкции create TABLE, но для этого необходимо заранее знать все типы данных в столбцах, прописывать их наименования, что занимает определённое время. Более того, в силу человеческого фактора не исключён риск совершения ошибок, которые приведут к лишним трудозатратам на пересоздание таблицы и потере времени при выполнении запроса.
Кто-то скажет: «А как же инструкция select INTO?». Да, эта инструкция позволяет сразу из запроса создать новую таблицу и записать туда результаты запроса выборки, но есть один большой очень критичный недостаток. На больших объёмах данных запросы, содержащие данную инструкцию занимают значительное количество ресурсов на сервере и блокируют работу других пользователей сервера. Обычно такие запросы отключаются администраторами серверов, а в некоторых случаях ещё и блокируются учётные записи пользователей, злоупотребляющих такими выгрузками.
В качестве решения вопроса можно применить следующий вариант. Учитывая, что инструкция select INTO копирует структуру результирующей таблицы, можно применить её к запросу, но не нагружая сервер, выбирать 0 строк (Select top 0 * into и т.д.). После этого, выполнить обычный запрос insert INTO во вновь созданную таблицу. Для того чтобы не делать это каждый раз (ведь главная цель – экономия времени), оформляем всё это в хранимую процедуру с использованием инструкции IF EXIST и данных из системных таблиц.
Таким образом, получаем следующий код:
Как видно из кода, на входе в процедуру требуется передать два параметра – наименование таблицы со схемой через точку (например, «dbo.MyTable») и SQL-запрос, результаты которого требуется записать в таблицу.
Вот так можно один раз потратить немного времени на написание процедуры и избавиться от мелких, но рутинных задач в дальнейшем. И это только один из вариантов, ведь у каждого программиста наверняка может найтись свой алгоритм оптимизации повседневных задач.
а не возникает вопроса - нафига пользователю разрешать создавать левую таблицу в sql -сервере?
В каждой организации могут происходить различные процессы по работе с данными, разные условия выполнения задач, где "книжные" классические методы ведения баз данных не работают. Например, когда пользователи самостоятельно анализируют данные и у них своя "песочница", где они создают таблицы, делают выборки и впоследствии удаляют за ненадобностью.
А то что если в первых тысячах строк будет varchar(20) а в следующих varchar (50) и произойдет усечение строк, никто не подумал?
Причём тут первая тысяча, если таблица создаётся по 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
SELECT col1, ....., col@ —