Как написать скрипт sql

Сергей Пятько

Сергей Пятько


Инженер-программист INOSTUDIO

Бывает такая ситуация, что необходимо проанализировать большой объём данных системы логирования событий на предмет аномалий или инцидентов. Просматривать такой массив данных трудно и нецелесообразно. Для этих целей можно обратиться к специализированному программному обеспечению, но нужно знать к какому. Не всегда есть время на изучение. И хорошо, если под конкретные задачи на примете есть несколько вариантов. А если их нет, тогда как быть?

Выход есть всегда, было бы желание. Поговорим о том, как можно довольно быстро загрузить некий массив таких данных куда-то и заняться его анализом. Для этого нам потребуется уже установленные:

  1. SQL Server 2017 или позднее;
  2. SQL Server Management Studio (SSMS);
  3. Понимание синтаксиса sql-запросов (SQL — Structured Query Language) хотя бы на базовом уровне. Если с этим пунктом есть трудности, можно обратиться к официальной документации Microsoft: Учебник. Составление инструкций Transact-SQL

Проверить версию установленного MS SQL Server можно при помощи sql-запроса в той же SSMS:

SELECT @@VERSION AS [SQL Server Version]

Результат выполнения запроса можно наблюдать на изображении ниже.

Или посмотреть версию SQL-сервера в Object Explorer, предварительно подключившись к нему.

Для выполнения sql-запросов использовалась SSMS версии 18.4 (более поздние версии также подойдут).

Internet Information Services и лог-файлы

В качестве эксперимента возьмём лог-файлы за пять дней с трёх серверов, на которых запущен Internet Information Services (IIS).

IIS — это веб-сервер, разработанный компанией Microsoft для своих операционных систем. Продукт полностью проприетарный и идёт в комплекте с Windows. Первая версия появилась в Windows NT и продолжает развиваться. По умолчанию IIS выключён в операционной системе.

Запустим диспетчер служб IIS на одном из серверов через меню «Пуск», написав в поисковой строке слово «IIS». Либо нажмите комбинацию клавиш Win+R, введите %SystemRoot%System32InetsrvInetmgr.exe и щёлкните «Ok».

После запуска диспетчера служб IIS (одним из двух способов) нам необходимо перейти в категорию Sites для определения значения ID. Оно понадобится нам для правильной идентификации каталога с лог-файлами интересующего нас сайта. Нам нужны логи для сайта с ID = 2.

Затем выбираем в левой секции Sites сайт по имени и затем в правой части раздела IIS нажимаем на Logging.

В группе Log Files находим расположение каталога (поле Directory), куда IIS сохраняет логи и формат сохраняемого файла (поле Format). В нашем случае лог-файлы сохраняется в W3C-формате. Подробнее с этим форматом можно познакомиться на официальном сайте Microsoft в руководстве W3C Logging. Копируем или запоминаем путь основного каталога с лог-файлами.

Чтобы просмотреть, какие поля включены для логирования, нажимаем на кнопку Select Fields. Эти данные понадобятся нам в дальнейшем для составления sql-скрипта и таблицы для хранения этих же значений. Так как мы забираем логи с 3-х машин, то отмеченные поля должны совпадать на всех машинах. Если по каким-то причинам есть расхождения, мы не сможем загрузить данные по логам в SQL ввиду их неконсистентности.

Далее переходим в директорию, куда IIS сохраняет логи. Структура папок будет такая: W3SVC[ID], где ID — значение нужного нам сайта. Забираем каталог с именем W3SVC2 или только часть содержимого этого каталога на локальную машину (логи за отдельный день с одной машины могут весить от 200 до 700 Мб). Эти действия по сохранению логов повторяем для оставшихся серверов.

Общий объём данных лог-файлов, собранных с серверов за 5 дней составил примерно 5 Гб на локальной машине.

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

Запускаем SSMS и подключаемся к локальному серверу.

Создание базы данных

Для начала нам нужно создать на локальном сервере базу данных (БД). Желательно создать её на твердотельном SSD-диске, чтобы подсистема ввода-вывода не стала узким местом при импорте и выполнении запросов на большом количестве данных. Можно сделать это двумя способами:

  1. написать скрипт;
  2. создать БД через интерфейс SSMS.

Для первого варианта воспользуемся инструкцией CREATE DATABASE. Более подробно с ней можно ознакомиться в разделе «Создание базы данных» с использованием Transact-SQL (T-SQL) официальной документации Microsoft. Итоговый скрипт будет выглядеть так (после создания скрипта не забываем выполнить его):

USE [master]

CREATE DATABASE [IISLogs] ON (
     NAME = [IISLogs]
    ,FILENAME = 'd:SQLDatabaseDATAIISLogs.mdf'
    ,SIZE = 8MB
    ,FILEGROWTH = 64MB
) LOG ON (
     NAME = [IISLogs_log]
    ,FILENAME = 'd:SQLDatabaseDATAIISLogs.ldf'
    ,SIZE = 8MB
    ,MAXSIZE = 1024MB
    ,FILEGROWTH = 64MB
)

Для второго варианта жмём правой кнопкой мыши на раздел с именем Databases и в контекстном меню выбираем пункт New Database.

В появившемся окне указываем имя БД, пути и лимиты на основную БД и её лог при необходимости.

Создание таблицы для хранения данных

Итак, у нас уже создана БД. Создадим таблицу для хранения логов. Для этого сверимся с заголовками, которые находятся в самих лог-файлах. Выберем один такой файл и откроем его. Нас интересует 4-я строка.

Копируем её и убираем значение #Fields:. Разделителем между данными служит пробел. С помощью него превращаем одну строку в набор строк и сверяемся с их количеством. В моём случае их получилось ровно 22. Соответственно, в итоговой таблице будет 22 столбца с такими же именами.

С именами столбцов определились, самое время написать скрипт создания таблицы с инструкцией CREATE TABLE. Подробную информацию о ней смотрите на сайте docs.microsoft.com. Итоговый скрипт будет выглядеть так (после создания скрипта не забываем выполнить его):

USE [IISLogs]

DROP TABLE IF EXISTS [dbo].[Log]

CREATE TABLE [dbo].[Log] (
     [date]            DATE           NULL
    ,[time]            TIME           NULL
    ,[s-sitename]      VARCHAR (1024) NULL
    ,[s-computername]  VARCHAR (1024) NULL
    ,[s-ip]            VARCHAR (16)   NULL
    ,[cs-method]       VARCHAR (16)   NULL
    ,[cs-uri-stem]     VARCHAR (4096) NULL
    ,[cs-uri-query]    VARCHAR (5120) NULL
    ,[s-port]          VARCHAR (4)    NULL
    ,[cs-username]     VARCHAR (40)   NULL
    ,[c-ip]            VARCHAR (16)   NULL
    ,[cs-version]      VARCHAR (256)  NULL
    ,[cs(User-Agent)]  VARCHAR (5120) NULL
    ,[cs(Referer)]     VARCHAR (5120) NULL
    ,[cs-host]         VARCHAR (1024) NULL
    ,[sc-status]       INT            NULL
    ,[sc-substatus]    INT            NULL
    ,[sc-win32-status] INT            NULL
    ,[sc-bytes]        INT            NULL
    ,[cs-bytes]        INT            NULL
    ,[time-taken]      INT            NULL
    ,[X-Forwarded-For] VARCHAR(1024)  NULL
    ,INDEX [cci] CLUSTERED COLUMNSTORE
)

Максимальные значения текстовых полей (VARCHAR) подобраны эмпирически и их размера вполне должно хватить для импортируемых данных. Но может возникнуть ситуация, когда импорт будет падать с ошибкой. Так может произойти, когда бот или сканер генерирует в запросах «паразитную» нагрузку и значение не помещается в максимальный размер поля. Тогда можно указать для всех текстовых полей максимальное значение параметром MAX (но лучше так не делать и найти «виновника» в данных для указания конечного размера по полю).

Импорт данных

Для импорта нам понадобятся следующие инструкции T-SQL:

  • xp_cmdshell
  • BEGIN TRANSACTION
  • COMMIT TRANSACTION
  • ROLLBACK TRANSACTION
  • TRY… CATCH
  • OBJECT_ID
  • FORMATMESSAGE
  • BULK INSERT

И сам итоговый скрипт.

USE [IISLogs]

   DECLARE @logFilePath VARCHAR(80)  = 'd:IISLoglogs'
   DECLARE @pattern   VARCHAR(8)   = '*.log'
   DECLARE @query     VARCHAR(512) = FORMATMESSAGE('master.dbo.xp_cmdshell "dir %s%s /s /b /o:d"', @logFilePath, @pattern)
          ,@tableName   VARCHAR(80)  = '[dbo].[Log]'
          ,@count     BIGINT     = 0
          ,@max       BIGINT
          ,@filename  VARCHAR(250)

BEGIN TRANSACTION
BEGIN TRY

    IF (OBJECT_ID(@tableName) IS NOT NULL) BEGIN

        CREATE TABLE #tmpDataFiles (
            [Id] BIGINT IDENTITY(1, 1) NOT NULL
           ,[Name] VARCHAR(200)
        )
        INSERT #tmpDataFiles EXEC (@query)
        DELETE #tmpDataFiles WHERE [Name] IS NULL

        SELECT * FROM #tmpDataFiles

        SET @max = (SELECT MAX([Id]) FROM #tmpDataFiles)

        WHILE @count <= @max BEGIN
            SET @count = @count + 1
            SET @filename = (SELECT [Name] FROM #tmpDataFiles WHERE [Id] = @count)
            SET @query = FORMATMESSAGE('BULK INSERT %s FROM ''%s'' WITH ( FIRSTROW = 1, FIELDTERMINATOR = '' '', ROWTERMINATOR = ''n'')', @tableName, @filename)

            IF (@filename IS NOT NULL) BEGIN
                PRINT @query
                EXEC (@query)
            END
        END
    END ELSE BEGIN
        PRINT FORMATMESSAGE('the %s table is not exists', @tableName)
    END

END TRY
BEGIN CATCH

    SELECT ERROR_NUMBER() AS ErrorNumber
          ,ERROR_SEVERITY() AS ErrorSeverity
          ,ERROR_STATE() AS ErrorState
          ,ERROR_PROCEDURE() AS ErrorProcedure
          ,ERROR_LINE() AS ErrorLine
          ,ERROR_MESSAGE() AS ErrorMessage
          ,@filename AS [FileName]
          ,@count AS [Count]
          ,@max AS [Max]

    IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;

END CATCH

IF @@TRANCOUNT > 0 COMMIT TRANSACTION

DROP TABLE IF EXISTS #tmpDataFiles

Примечание. В приведённом sql-скрипте по импорту данных можно обойтись без использования таких операторов, как:

  • BEGIN TRANSACTION;
  • COMMIT TRANSACTION;
  • ROLLBACK TRANSACTION.

Запускаем скрипт и идём наливать чай, так как время выполнения импорта может занять от 2 и более минут в зависимости от объёма данных, находящихся в лог-файлах. Результат выполнения скрипта можно увидеть, если нажать на вкладку Messages.

Импорт завершён. Теперь можно узнать, сколько данных мы загрузили. Для этого выполним такой запрос:

SELECT FORMAT(COUNT(*), 'N', 'ru-RU') AS [Count]
  FROM [IISLogs].[dbo].[Log]

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

Например, можно посмотреть, сколько было запросов, с каких IP-адресов и где сервер возвращал в таких запросах статус 404.

SELECT [sc-status]
        ,[X-Forwarded-For]
        ,COUNT(*) AS [Count]
    FROM [IISLogs].[dbo].[Log]
   WHERE [sc-status] = 404
     AND [date] = '2022-01-17'
     AND [time] BETWEEN '00:00:00.000' AND '23:59:59.999'
GROUP BY [sc-status]
        ,[X-Forwarded-For]
  HAVING COUNT(*) > 100
ORDER BY [Count] DESC

Сразу виден топ IP-адресов по количеству запросов. Это либо боты, либо сканеры. Берём первый IP из списка и смотрим на его запросы. И убеждаемся, что это действительно бот/сканер.

SELECT [cs-method]
        ,[cs-uri-stem]
        ,[cs-uri-query]
        ,[cs(User-Agent)]
        ,[sc-status]
        ,COUNT(*) AS [Count]
    FROM [IISLogs].[dbo].[Log]
   WHERE [date] = '2022-01-17'
     AND [time] BETWEEN '00:00:00.000' AND '23:59:59.999'
     AND [X-Forwarded-For] = '128.199.XXX.101'
GROUP BY [cs-method]
        ,[cs-uri-stem]
        ,[cs-uri-query]
        ,[cs(User-Agent)]
        ,[sc-status]
ORDER BY [Count] DESC

Вот так относительно просто можно заниматься аналитикой «небольшого» объёма данных лог-файлов. И необязательно это могут быть только логи с IIS. Загружать в БД SQL для анализа можно почти всё что угодно, было бы желание.

concatenate sqlSQL or Structured Query Language is a powerful and standard database computer language. It is used with all the RDBM’s to retrieve and manage data. There are three categories of commands in SQL. They are DDL(Data Definition Language), DML(Data Manipulation Language) and DCL(Data Control Language). Examples of Software that use SQL are MYSQL, Oracle, Sybase, SQL Server and more. Though SQL is very good at creating, retrieving and manipulating data, by itself, it lacks the basic programming features. PL/SQL is used to include SQL statements in data driven programs.

Today we walk you through the Graphical User Interface known as SQL Scripts, which help to manage script files. The latter contain the different SQL commands as well as PL/SQL blocks. If the script file contains SQL*Plus commands they are ignored at the time of execution. We assume that you are familiar with the different SQL commands and PL/SQL, if not you can take this course on how the essentials of SQL for PL/SQL programming.

What is a SQL script

A SQL script is a group of SQL commands saved a single file. This file can contain both SQL statements as well as PL/SQL blocks. You can learn more about SQL commands in this course.

What is SQL Scripts

The SQL Scripts is part of a Graphical User Interface from Oracle which helps to deal with all aspects of script files. SQL Scripts is an environment that enables you to create, edit, delete script files, and also execute them.

Advantages of using script files

  • No need for user action- Instead of executing a single SQL command at time from the command prompt, we can include several SQL commands in a single script file.
  • Saves time– When you run the script file, a number of SQL commands will execute sequentially. This is more convenient and saves time.

To truly appreciate the power of scripts, take this course on SQL server essentials. Lets go through each operation to understand how to use SQL Scripts better.

How to Access SQL Scripts

To access the SQL Scripts, you need to first log in to the home page of the Workspace.

Next step is to view the SQL Scripts, you have to select the SQL Workshop icon’s down arrow and choose the option SQL Scripts from the drop down menu.

How to create SQL Script

There are two methods. Here we look at the first method.

  1. Using the Script Editor
  • Go to the SQL Scripts page and select the create button. This opens the script editor.
  • You can enter the name of the script file in the Script Name field. Note that the extension names are not mandatory.
  • You can include, the SQL statements, PL/SQL blocks and SQL*Plus commands.
  • Finally, save the script file by clicking on the Save button.
  1. The second method is to upload from the local file system.
  • In the SQL Scripts page, click on the Upload button. This opens a dialog box.
  • You can either browse for the concerned file or enter the name and path of the file.
  • When you click on the Upload button, it uploads the file to the Script Repository.

What does the Script Editor do

You can add content to the existing file, edit existing content, execute or delete scripts stored in the Script repository.

How to Edit a SQL Script

  • Load an existing script file into the Script Editor. There are two ways to do it.
    1. You can click the desired script icon displayed in the Icons view.
    2. Another way is to click the Edit icon in the Details view.
  • If you do  any of the above mentioned actions, the Script Editor will open.
  • Then you can edit the script and save it to the repository.

How to delete a SQL Script

There are two ways to delete Scripts from the Scripts repository. Let’s take a look at the first method.

  1. First Method
  • On the SQL Scripts there is the View List. From the latter, select details.
  • Next click on Go item to select the scripts that is to be deleted.
  • You have the option to select the individual script or select all the scripts in the current page by clicking on the relevant check boxes.
  • You will be prompted to confirm the deletion. Once done the deletion is permanent and a message will be displayed.
  1. Second Method
  • Here the Script Editor is used to open the desired script. Next, click delete.
  • You will be prompted to confirm before the deletion.
  • Then the Script is permanently deleted from the Script repository after which a message is displayed.

How to copy a SQL Script

This can be done by saving the script in the Script Repository with a new name in the editor.

How to execute a SQL Script

  • On the View list of the SQL scripts page, select details.
  • Next click Go.
  • Then the details view will appear. Here click the Run icon of the desired script that you want to run.
  • Next the Run Script page is opened. This page will display the errors. In case there are errors, you need to click on Edit Script which is on the Run Script page. If there are no errors, click on run which is on the Run Script page. This will execute the script.
  • On the SQL Scripts page, go to the Tasks list and click on Manage results.
  • Then go to the Icons view, click on the Show Results click box and the desired Icon. This will display the Manage Script Results page, which lists the scripts available results.

How to view the SQL Scripts results

Hope this article on SQL Scripts gave you a clear insight about how to create and manage script file. Study the theory and implement the different operations to gain proficiency in this GUI editor. To know more about SQL recommend you to take this course on advanced SQL concepts.

concatenate sqlSQL or Structured Query Language is a powerful and standard database computer language. It is used with all the RDBM’s to retrieve and manage data. There are three categories of commands in SQL. They are DDL(Data Definition Language), DML(Data Manipulation Language) and DCL(Data Control Language). Examples of Software that use SQL are MYSQL, Oracle, Sybase, SQL Server and more. Though SQL is very good at creating, retrieving and manipulating data, by itself, it lacks the basic programming features. PL/SQL is used to include SQL statements in data driven programs.

Today we walk you through the Graphical User Interface known as SQL Scripts, which help to manage script files. The latter contain the different SQL commands as well as PL/SQL blocks. If the script file contains SQL*Plus commands they are ignored at the time of execution. We assume that you are familiar with the different SQL commands and PL/SQL, if not you can take this course on how the essentials of SQL for PL/SQL programming.

What is a SQL script

A SQL script is a group of SQL commands saved a single file. This file can contain both SQL statements as well as PL/SQL blocks. You can learn more about SQL commands in this course.

What is SQL Scripts

The SQL Scripts is part of a Graphical User Interface from Oracle which helps to deal with all aspects of script files. SQL Scripts is an environment that enables you to create, edit, delete script files, and also execute them.

Advantages of using script files

  • No need for user action- Instead of executing a single SQL command at time from the command prompt, we can include several SQL commands in a single script file.
  • Saves time– When you run the script file, a number of SQL commands will execute sequentially. This is more convenient and saves time.

To truly appreciate the power of scripts, take this course on SQL server essentials. Lets go through each operation to understand how to use SQL Scripts better.

How to Access SQL Scripts

To access the SQL Scripts, you need to first log in to the home page of the Workspace.

Next step is to view the SQL Scripts, you have to select the SQL Workshop icon’s down arrow and choose the option SQL Scripts from the drop down menu.

How to create SQL Script

There are two methods. Here we look at the first method.

  1. Using the Script Editor
  • Go to the SQL Scripts page and select the create button. This opens the script editor.
  • You can enter the name of the script file in the Script Name field. Note that the extension names are not mandatory.
  • You can include, the SQL statements, PL/SQL blocks and SQL*Plus commands.
  • Finally, save the script file by clicking on the Save button.
  1. The second method is to upload from the local file system.
  • In the SQL Scripts page, click on the Upload button. This opens a dialog box.
  • You can either browse for the concerned file or enter the name and path of the file.
  • When you click on the Upload button, it uploads the file to the Script Repository.

What does the Script Editor do

You can add content to the existing file, edit existing content, execute or delete scripts stored in the Script repository.

How to Edit a SQL Script

  • Load an existing script file into the Script Editor. There are two ways to do it.
    1. You can click the desired script icon displayed in the Icons view.
    2. Another way is to click the Edit icon in the Details view.
  • If you do  any of the above mentioned actions, the Script Editor will open.
  • Then you can edit the script and save it to the repository.

How to delete a SQL Script

There are two ways to delete Scripts from the Scripts repository. Let’s take a look at the first method.

  1. First Method
  • On the SQL Scripts there is the View List. From the latter, select details.
  • Next click on Go item to select the scripts that is to be deleted.
  • You have the option to select the individual script or select all the scripts in the current page by clicking on the relevant check boxes.
  • You will be prompted to confirm the deletion. Once done the deletion is permanent and a message will be displayed.
  1. Second Method
  • Here the Script Editor is used to open the desired script. Next, click delete.
  • You will be prompted to confirm before the deletion.
  • Then the Script is permanently deleted from the Script repository after which a message is displayed.

How to copy a SQL Script

This can be done by saving the script in the Script Repository with a new name in the editor.

How to execute a SQL Script

  • On the View list of the SQL scripts page, select details.
  • Next click Go.
  • Then the details view will appear. Here click the Run icon of the desired script that you want to run.
  • Next the Run Script page is opened. This page will display the errors. In case there are errors, you need to click on Edit Script which is on the Run Script page. If there are no errors, click on run which is on the Run Script page. This will execute the script.
  • On the SQL Scripts page, go to the Tasks list and click on Manage results.
  • Then go to the Icons view, click on the Show Results click box and the desired Icon. This will display the Manage Script Results page, which lists the scripts available results.

How to view the SQL Scripts results

Hope this article on SQL Scripts gave you a clear insight about how to create and manage script file. Study the theory and implement the different operations to gain proficiency in this GUI editor. To know more about SQL recommend you to take this course on advanced SQL concepts.

Привет! Сегодня мы поговорим о том, как можно сгенерировать SQL скрипты создания объектов базы данных Microsoft SQL Server, включая сами данные, стандартными средствами SQL Server Management Studio (SSMS).

SQL скрипты создания объектов базы данных Microsoft SQL Server

Содержание

  1. Что такое SQL скрипт объекта базы данных?
  2. Что могут содержать SQL скрипты?
  3. Для чего могут потребоваться SQL скрипты объектов базы данных?
  4. Как создать SQL скрипт объекта базы данных в Microsoft SQL Server?
  5. Создание SQL скрипта объекта базы данных Microsoft SQL Server
  6. Шаг 1 – Запускаем SSMS
  7. Шаг 2 – Запускаем задачу «Сформировать скрипты»
  8. Шаг 3 – Выбираем объекты для включения в SQL скрипт
  9. Шаг 4 – Задание параметров SQL скрипта
  10. Шаг 5 – Проверка параметров и запуск процесса создания скрипта
  11. Шаг 6 – Завершение процесса и результат
  12. Видео-инструкция

SQL скрипт объекта базы данных – это SQL инструкция, с помощью которой создается этот объект, сохраненная в текстовом файле.

Иными словами, это простой SQL запрос, обычно сохраненный в текстовом файле с расширением .sql. В этом SQL запросе содержатся все необходимые инструкции создания объекта (или объектов), включая инструкции наполнения его данными.

Такой SQL скрипт можно открыть любым текстовым редактором, скопировать текст SQL запроса и выполнить, например, в среде SQL Server Management Studio, таким образом, создав объект базы данных, не разрабатывая соответствующие SQL инструкции самостоятельно.

Также SQL скрипты можно открыть специальными программами, которые умеют работать с SQL скриптами, и выполнять их на базе данных.

Что могут содержать SQL скрипты?

SQL скрипты объектов базы данных могут содержать:

  • Инструкции создания таблиц (CREATE);
  • Заполнение таблиц (инструкции INSERT);
  • Определение представлений, функций, хранимых процедур, триггеров;
  • Определение ограничений и индексов;
  • Определение создания других объектов;
  • И другие SQL инструкции.

Для чего могут потребоваться SQL скрипты объектов базы данных?

SQL скрипты объектов базы данных могут потребоваться администраторам или разработчикам, например, для того, чтобы в случае необходимости иметь возможность быстро восстановить эти объекты.

Или для того, чтобы передать эти SQL скрипты другому администратору, разработчику или заказчику, чтобы он создал подобные объекты на своем экземпляре SQL Server.

Таким образом, такие SQL скрипты необходимы для хранения копий SQL инструкций, с помощью которых создавались объекты базы данных.

Как создать SQL скрипт объекта базы данных в Microsoft SQL Server?

Так как SQL скрипт – это обычный текстовый файл, его можно создать вручную, например, когда Вы разрабатываете объект БД, Вы просто сохраняете SQL инструкцию в файл, и добавляете в него по мере необходимости другие SQL инструкции.

Однако также возможно автоматически сгенерировать SQL скрипты объектов базы данных специальными инструментами, например, в среде SQL Server Management Studio (SSMS). А как это делается, я сейчас и покажу.

Заметка! Если Вас интересует SQL и T-SQL, рекомендую посмотреть мои видеокурсы по T-SQL, с помощью которых Вы «с нуля» научитесь работать с SQL и программировать с использованием языка T-SQL в Microsoft SQL Server.

Создание SQL скрипта объекта базы данных Microsoft SQL Server

В качестве исходных данных у меня будет база данных TestDB и таблица Goods, SQL скрипт которой мне и нужно создать. При этом мне необходимо, чтобы скрипт включал не только определение инструкции CREATE, но и данные, которые содержит эта таблица.

В качестве инструмента я буду использовать SQL Server Management Studio.

Итак, давайте начнем.

Шаг 1 – Запускаем SSMS

Сначала запускаем среду SQL Server Management Studio любым удобным для Вас способом, иными словами, никаких особых манипуляций с открытием SSMS выполнять не требуется.

Шаг 2 – Запускаем задачу «Сформировать скрипты»

Далее в обозревателе объектов находим нужную нам базу данных, затем открываем контекстное меню правой кнопкой мыши, ищем пункт «Задачи», и выбираем задачу «Сформировать скрипты».

Скриншот 1

В итоге запустится мастер создания скриптов. В окне «Введение» можем сразу нажать «Далее».

Скриншот 2

Курс по SQL для начинающих

Шаг 3 – Выбираем объекты для включения в SQL скрипт

После этого нам нужно выбрать объекты базы данных, которые необходимо включить в SQL скрипт. При этом нам доступно два варианта:

  • Создать скрипт для всей базы данных и всех ее объектов – этот вариант предполагает, что Вам нужен скрипт создания всех объектов в БД;
  • Выбрать отдельные объекты базы данных – в данном случае в скрипт включатся SQL инструкции только тех объектов, которые Вы укажете.

Так как мне нужно сохранить только одну таблицу, я выбираю второй вариант и отмечаю нужную таблицу, т.е. в моем случае Goods.

Нажимаю «Далее».

Скриншот 3

Шаг 4 – Задание параметров SQL скрипта

Теперь мы можем указать параметры формирования скрипта, в частности, каким образом мы хотим получить скрипт.

Доступно 3 способа:

  • Сохранить в файл – при этом мы можем сами указать нужный нам каталог для сохранения;
  • Сохранить в буфер обмена;
  • Сохранить в новое окно запросов.

Также есть и дополнительные параметры, чтобы их открыть, необходимо нажать на соответствующую кнопку.

Скриншот 4

Заметка! Обзор инструментов для работы с Microsoft SQL Server.

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

Также Вы можете включить в скрипты инструкции DROP на случай, если Вам нужно пересоздать объекты.

После того как все параметры заданы, нажимаем «ОК», а после для продолжения кнопку «Далее».

Скриншот 5

Шаг 5 – Проверка параметров и запуск процесса создания скрипта

На данном шаге все проверяем и запускаем сам процесс формирования скрипта, т.е. нажимаем «Далее».

Скриншот 6

Шаг 6 – Завершение процесса и результат

Когда процесс будет завершен, программа сообщит Вам об этом, нажимаем «Готово».

Скриншот 7

В результате в каталоге, который Вы указали в параметрах формирования скрипта, появится SQL скрипт, а по факту обычный текстовый файл с расширением .sql.

Если его открыть, например, текстовым редактором, то можно посмотреть на все SQL инструкции. Они будут выглядеть примерно следующим образом.

Скриншот 8

Видео-инструкция

На сегодня это все, надеюсь, материал был Вам полезен, пока!


октябрь
16
, 2016

Когда разрабатываешь веб-приложение не один, а в команде и/или на нескольких машинах, рано или поздно сталкиваешься с проблемой синхронизации кода проекта и базы данных. Для управления кодом есть системы контроля версий, в частности, git, а для СУБД придуманы миграции.

Есть много готовых разнообразных инструментов, которые занимаются миграциями, но!

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

Поэтому всех, кому интересно узнать, как самим сделать простую утилиту миграций, написав полсотни строк php-кода, прошу в статью.

Идея миграций

Идея довольно проста: в проекте создаем отдельную папку sql, куда складываем sql-файлы с миграциями, то есть, со скриптами, которые меняют содержимое базы,
а также один php-файл, который эти миграции и накатывает.

Нужно учесть 2 вещи: во-первых, каждая миграция должна выполняться строго один раз, а во-вторых, в строго определенном порядке.
Это разумно и обязательно, потому как если нам прилетают от коллеги 2 миграции, одна из которых создает таблицу users,
а другая добавляет в нее тестовых пользователей, то мы хотим выполнить эти скрипты именно в таком порядке
и не добавить при этом данные в базу больше одного раза.

Проблему повторных выполнений миграций мы решим, записывая в отдельную таблицу уже отработавшие скрипты,
а порядок выполнения установим четкими правилами именования sql-файлов.
Как это решается в коде, увидим чуть позже, а пока займемся подготовкой самих тестовых миграций
(исходники всех миграций и php-скрипта в конце статьи)

Создаем тестовые sql-скрипты

Пусть у нас есть тестовая база данных под названием test.
Мы работаем с ней какое-то время и решили внедрить миграции.
Есть разумное правило: самая первая миграция должна содержать в себе полный дамп уже существующих сущностей в базе.
Уточню: миграции помогают не только последовательно расширять уже существующую базу, но еще и накатить эту самую базу с нуля,
например, для новых людей в команде.

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

В тестовом примере рассмотрим такой ход событий.

Первая миграция накатывает уже существующие данные и создает таблицу versions — она содержит уже выполненные скрипты.

Вторая создает таблицу users с тремя полями: id, email, password.

Третья добавляет в users три тестовых записи.

А четвертая добавляет в users новую колонку active.

Напишем первую миграцию: дамп базы и таблица versions.
Пусть на момент внедрения миграций у нас есть таблица goods с парой товаров.
Их нужно скинуть в скрипт и в тот же скрипт добавить таблицу versions.
В итоге файл будет выглядеть так.

0000_base.sql

    -- Дамп существующей базы --
    
    -- Таблица товаров --
    create table `goods` (
        `id` int(10) unsigned not null auto_increment,
        `name` varchar(255) not null,
        `price` int(11) not null,
        primary key (id)
    )
    engine = innodb
    auto_increment = 1
    character set utf8
    collate utf8_general_ci;
    
    -- Данные из таблицы товаров --
    insert into `goods` (`name`, `price`) values 
        ('Ноутбук', 30000),
        ('Телефон', 20000);
    
    -- /Дамп существующей базы --
    
    
    -- Таблица versions --
    create table if not exists `versions` (
        `id` int(10) unsigned not null auto_increment,
        `name` varchar(255) not null,
        `created` timestamp default current_timestamp,
        primary key (id)
    )
    engine = innodb
    auto_increment = 1
    character set utf8
    collate utf8_general_ci;    

В файле мы видим структуру goods и 2 строчки с данными, а также versions.
Эта таблица содержит 3 столбца: первичный ключ id, name — имя файла с миграцией, created — дата ее накатывания.
Как Вы догадываетесь, в versions мы будем добавлять строки после накатывания новых миграций.
А пока создадим оставшиеся 3 миграции.

0002_add_users.sql

    -- Таблица пользователей --
    create table if not exists `users` (
        `id` int(10) unsigned not null auto_increment,
        `email` varchar(255) not null,
        `password` varchar(255) not null,
        primary key (id)
    )
    engine = innodb
    auto_increment = 1
    character set utf8
    collate utf8_general_ci;

0003_insert_data_into_users.sql

    -- Добавляем тестовых пользователей --
    insert into `users` (`email`, `password`) values 
        ('test1@gmail.com', '111111'),
        ('test2@gmail.com', '222222'),
        ('test3@gmail.com', '333333')

0004_add_column_active_to_users.sql

    -- Добавляем колонку active в users --
    alter table `users` 
        add column `active` tinyint(1) not null default 1 after `password`;

На заметку: возможно, Вам не удобно писать sql-скрипты руками, Вы привыкли создавать и заполнять таблицы через phpMyAdmin
или другой инструмент. Спешу успокоить, все известные мне утилиты позволяют генерировать такой sql-код автоматически.
То есть Вы можете работать с базой, как удобно, а при подготовке файла-миграции вытащить нужный скрипт из условного phpMyAdmin-a в режиме copy-paste.

Обратим внимание на правила наименования файлов — это важная часть.

  • 0001_base.sql
  • 0002_add_users.sql
  • 0003_insert_data_into_users.sql
  • 0004_add_column_active_to_users.sql

Порядковые номера в начале каждого файла нужны, чтобы правильно отсортировать файлы.
Только в этом случае миграции будут выполняться в правильном порядке.
После _ идет краткое описание миграции, которое нужно исключительно для нашего удобства,
чтобы понимать, что делает тот или иной скрипт, не заглядывая в него.

В нашем варианте мы предполагаем, что миграций не будет больше 9999 штук, и номер всегда должен состоять из 4-х цифр.
Например, 10-я миграция будет называться 0010_description, а 101-я — 0101_description.

Теперь у нас все готово к написанию php-скрипта для выполнения миграций — migration.php.

Пишем php-код для запуска миграций

Подумаем, что нам нужно уметь делать.

  • Во-первых, получить список всех sql-файлов из папки sql.
  • Во-вторых, понять, какие из них уже накатились ранее (сравнить этот список с тем, что лежит в таблице versions).
  • В-третьих, залить содержимое отобранных файлов в базу, заодно записав в versions их названия.

Пожалуй все, остальные операции довольно просты, разберем их по ходу пьесы.

Можно писать код.

Каркас migration.php, базовые константы и функции

Нам нужно написать фунцию подключения к базе данных и общую логику работы скрипта.
Создадим файл migration.php, кинем его в папку sql рядом с миграциями и напишем в нем следующее:

    // Объявляем нужные константы
    define('DB_HOST', 'localhost');
    define('DB_USER', 'root');
    define('DB_PASSWORD', 'root');
    define('DB_NAME', 'test');
    define('DB_TABLE_VERSIONS', 'versions');
    
    
    // Подключаемся к базе данных
    function connectDB() {
        $errorMessage = 'Невозможно подключиться к серверу базы данных';
        $conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
        if (!$conn)
            throw new Exception($errorMessage);
        else {
            $query = $conn->query('set names utf8');
            if (!$query)
                throw new Exception($errorMessage);
            else
                return $conn;
        }
    }
    
    
    // Получаем список файлов для миграций
    function getMigrationFiles($conn) {
        // ...
    }
    
    
    // Накатываем миграцию файла
    function migrate($conn, $file) {
        // ...
    }
    
    
    // Стартуем
    
    // Подключаемся к базе
    $conn = connectDB();
    
    // Получаем список файлов для миграций за исключением тех, которые уже есть в таблице versions
    $files = getMigrationFiles($conn);
    
    // Проверяем, есть ли новые миграции
    if (empty($files)) {
        echo 'Ваша база данных в актуальном состоянии.';
    } else {
        echo 'Начинаем миграцию...

'; // Накатываем миграцию для каждого файла foreach ($files as $file) { migrate($conn, $file); // Выводим название выполненного файла echo basename($file) . '
'; } echo '
Миграция завершена.'; }

Пробежимся по коду.

  • Сначала объявляем константы для подключения к базе и с названием таблицы versions (она будет упоминаться в коде несколько раз).
  • Функция connectDB возвращает mysqli-объект для работы с базой.
  • getMigrationFiles($conn) возвращают список актуальных, еще не выполненых миграций.
  • migrate($conn, $file) накатывает одну миграцию — по имени файла.

Дальше сама логика работы.

  • Подключаемся к базе и получаем список актуальных миграций.
  • Если он пустой, то просто выводим сообщение, что база в актуальном состоянии.
  • Если файлы миграции имеются, то запускаем для каждого функцию migrate, выводя название файла для информации.
    А в конце пишем позитивное сообщение, что миграция завершена.

Теперь нам нужен код для getMigrationFiles()

    // Получаем список файлов для миграций
    function getMigrationFiles($conn) {
        // Находим папку с миграциями
        $sqlFolder = str_replace('\', '/', realpath(dirname(__FILE__)) . '/');
        // Получаем список всех sql-файлов
        $allFiles = glob($sqlFolder . '*.sql');
    
        // Проверяем, есть ли таблица versions 
        // Так как versions создается первой, то это равносильно тому, что база не пустая
        $query = sprintf('show tables from `%s` like "%s"', DB_NAME, DB_TABLE_VERSIONS);
        $data = $conn->query($query);
        $firstMigration = !$data->num_rows;
        
        // Первая миграция, возвращаем все файлы из папки sql
        if ($firstMigration) {
            return $allFiles;
        }
    
        // Ищем уже существующие миграции
        $versionsFiles = array();
        // Выбираем из таблицы versions все названия файлов
        $query = sprintf('select `name` from `%s`', DB_TABLE_VERSIONS);
        $data = $conn->query($query)->fetch_all(MYSQLI_ASSOC);
        // Загоняем названия в массив $versionsFiles
        // Не забываем добавлять полный путь к файлу
        foreach ($data as $row) {
            array_push($versionsFiles, $sqlFolder . $row['name']);
        }
    
        // Возвращаем файлы, которых еще нет в таблице versions
        return array_diff($allFiles, $versionsFiles);
    }

Почти каждая строка прокомментирована, но поясню еще подробнее.

В переменную $sqlFolder попадает полный абсолютный путь к текущему файлу migration.php.
А соответственно, и к папке sql с миграциями.
Замена \ на / нужна для тех случаев, когда realpath возвращает путь с обратными слешами вместо прямых
(например, в windows). Первый нужен для экранирования второго.

Дальше функция glob вытащит все файлы из указанной папки по нужной маске *.sql.

Затем нужно понять, не в первый ли раз мы собираемся накатывать миграции.
Определить это можно только по наличию таблицы versions в базе.
Мы же помним, что она создается в самой первой миграции.
Если запрос show tables from test like «versions» вернет пустой список, значит таблицы еще нет,
в переменную $firstMigration запишем true и вернем из функции весь список файлов.

Если же таблица versions существует, то вытаскиваем из нее список файлов — уже выполненные миграции.
И возвращаем из функции файлы, которых нет в таблице versions.
В этом поможет array_diff.

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

    // Накатываем миграцию файла
    function migrate($conn, $file) {
        // Формируем команду выполнения mysql-запроса из внешнего файла
        $command = sprintf('mysql -u%s -p%s -h %s -D %s < %s', DB_USER, DB_PASSWORD, DB_HOST, DB_NAME, $file);    
        // Выполняем shell-скрипт
        shell_exec($command);
    
        // Вытаскиваем имя файла, отбросив путь
        $baseName = basename($file);
        // Формируем запрос для добавления миграции в таблицу versions
        $query = sprintf('insert into `%s` (`name`) values("%s")', DB_TABLE_VERSIONS, $baseName);
        // Выполняем запрос
        $conn->query($query);
    }

Из интересного в этой функции только shell_exec($command) — выполнение строки $command в терминале.
Залить содержимое sql-файла в базу можно такой командой

mysql -uuser -ppassword -h host -D database < file.sql

Оную команду формируем с помощью sprintf и передаем ее в shell_exec.
Собственно миграция накатилась, осталось добавить соответствующее название файла в таблицу versions —
это заурядный запрос вида

insert into `versions` (name) values(‘0001_base.sql’)

И это весь код, который нужен нам для создания простой системы миграций.
Теперь создадим пустую базу данных test, закинем, если еще не успели, папку sql куда-нибудь в проект и откроем в браузере sql/migration.php.

На заметку: если Вы не хотите на боевом сайте светить содержимым своих миграций возможным злоумышленникам,
то поместите сами sql-миграции в место, недоступное для просмотра извне.
migration.php можно закинуть куда угодно, хоть в корень проекта, только придется немного поправить пути к папке с миграциями.
Думаю, с этим делом Вы без труда справитесь сами :-)

Итак, migration.php в браузере запущен, если все сделано правильно, то увидим такую картину

    Начинаем миграцию...
    
    0001_base.sql
    0002_add_users.sql
    0003_insert_data_into_users.sql
    0004_add_column_active_to_users.sql
    
    Миграция завершена.

Посмотрите в базу и убедитесь, что нужные таблицы и данные созданы, в versions лежат 4 строки с названиями файлов.
Теперь обновите страницу в браузере и увидите сообщение «Ваша база данных в актуальном состоянии.»
Все правильно, все миграции сделаны, а новых пока нет.

Чтобы окончательно убедиться в работоспособности системы, удалите все три таблицы из базы и оставьте в папке sql только первую миграцию.
Обновите страницу — накатится одна миграция, таблица goods и versions с единственной строкой.
Добавьте в папку миграции 0002_add_users.sql и 0003_insert_data_into_users.sql, обновите, выполнятся еще 2 миграции и в базе появится users с данными.
И наконец последний файл и снова запуск — в users добавится новая колонка active.

Итоги и исходники

Что же у нас получилось?

Все работает, как мы и задумали.

Теперь можно править базу, добавляя все изменения с ней в миграции,
не боясь, что кто-то и когда-то будет работать с неактуальной базой.

Главное, не забывать в нужные моменты при изменении базы создавать соответствующие миграции, соблюдая правила именования файлов,
и запускать скрипт migration.php.

Как видим, код получился действительно короткий и простой (половину занимают комментарии).
И при этом прямые свои обязанности он выполняет — накатывает миграции, не выполняя ничего лишнего.

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

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

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

Задавайте вопросы и оставляйте отзывы в комментариях, и конечно, скачивайте исходники

Анонсы статей, обсуждения интернет-магазинов, vue, фронтенда, php, гита.

Истории из жизни айти и обсуждение кода.

A discussion on writing SQL scripts and some quick examples.

In the previous lesson, we added data to our database table using the «Edit Top 200 Rows» option. In this lesson, we will look at how to write SQL scripts to update and run queries against our database.

SQL scripts can be used to insert data, read data, update data, and delete data. They can also be used to create database objects such as tables, views, stored procedures, and they can even be used to create whole databases themselves — complete with tables, data, users, etc.

Transact-SQL

SQL Server supports Transact-SQL as a scripting language. Transact-SQL is based on SQL (Structured Query Language), which is the programming language used to interface between applications and their databases. Transact-SQL is a relatively easy language to learn and I highly recommend becoming familiar with it. Whenever I refer to a SQL script here, I mean a Transact-SQL script.

SQL Statements

SQL scripts are usually made up of one or more «statements». Each statement tells SQL Server what to do.

SQL scripts can contain many statements. For example, a SQL script could contain a statement to CREATE a table, another statement to INSERT data into that table, and another statement to SELECT all the data that was just inserted into the table. In fact, SQL has specific statements that are used for those exact three things: the CREATE statement, the INSERT statement, and the SELECT statement.

Generally speaking, your statements will begin with the word of the task that you’re trying to perform. If you’re trying to create a database object, your statement will start with CREATE. I say «generally speaking» because, there are some other bits and pieces that you can throw in to a SQL statement that may come prior to your statement.

Example SQL Statement

Probably the easiest SQL statement to learn is the SELECT statement. Here’s an example of a SELECT statement at its simplest:

The above statement selects all columns from the Tasks table. The asterisk (*) means «all columns». The above statement could be modified slightly to only return a particular column, and we could add a WHERE clause to filter the data to only those records that we’re interested in:

The above statement selects the TaskName column from the Task table, but it only returns those that have a StatusId of 3. The value of 3 could mean «To Do» or «Done» or whatever it is we want it to mean. In our TaskTracker database, we’ll be creating a new table called Status where we’ll specify what «3» means (and «1» and «2» of course). These numbers are simply the values in the StatusId field (which we specified as an Identity column — an autonumber). Each of those numbers will have a corresponding value in the StatusName field which will tell us what status it actually is.

Then, once we’ve created our Status table, we could modify the above SQL statement to include the Status table so that we can write WHERE StatusName = "To Do" instead of trying to remember what number «To Do» is.

But we need to create our Status table first…

Creating Tables with a SQL Script

Below is a SQL script that will another table on our database — a Status table. If you aren’t familiar with SQL it might look a bit weird. But I’m sure you’ll have some idea of what it does when you see the names of the columns and their corresponding data types. In this script, we aren’t allowing any NULL fields (hence the NOT NULL next to each column). We’re also creating a primary key for the StatusId field, and we’re setting a default value to the DateCreated field to (getdate()).

To run this script, do the following:

  1. Copy the script to your clipboard
  2. In the SQL Server Management Studio, click the New Query button on the toolbar:
  3. Paste the script into the query window
  4. Click the ! Execute button on the toolbar:

Once the script has run, you should see a message that reads Command(s) completed successfully.

Screenshot of the New Query button

Here’s the script:

Keyboard Shortcut

You can also run a query by pressing F5 on your keyboard.

Plus, you can even run part of a query by selecting the part that you want to run, then pressing F5. This works well on larger scripts that contain a lot of SQL statements, but when for some reason, you only want to run one or two (or even run all of them but just one at a time).

Add Data via SQL Script

You can also add data via a SQL script. The script will use the INSERT statement to insert data into the tables that you specify. You can have the script insert data into all columns in the table, or just those that you specify.

The following script inserts data into the Status table, and then selects that data (so we can see that it went in). Run this script the same way you did with the above script):

And here’s what that looks like:

Screenshot SQL query results

As you can see, the results of the query are displayed in the bottom pane.

Cross Reference Data

Now that we’ve got our Status table, let’s add a value to the StatusId field of the Tasks table (remember we left that field blank for all records because we didn’t yet have the Status table).

So the value we add is going to link the Tasks table to the Status table. Each record in the Tasks table will now have a StatusId which will be either 1, 2 or 3 (to match a value in the StatusId field of the Status table).

To do this, we’ll need to use an UPDATE statement (because we’re updating the records rather than inserting new ones).

So without further ado, let’s run the following script:

And you should now see your Tasks table, complete with its StatusId field populated for all records. Something like this:

Screenshot SQL query results

Combining Scripts

Actually, we could just have easily combined all of the above scripts and run them as one. I only kept them separate in order to make it easier to understand which part does what.

If you’d like to learn more about creating SQL statements, check out my SQL tutorial.

Case Sensitivity

SQL is case insensitive. So the following statements all mean the same thing:

  • SELECT * FROM TASKS
  • SELECT * FROM Tasks
  • Select * From Tasks
  • select * from tasks

Database Administration

Most of the database administration tasks (such as creating users, backups, etc) that can be performed in SSMS via the graphical user interface can be performed programatically via SQL scripts. This tutorial concentrates on using the graphical user interface, mainly because it’s usually a lot easier for new users to get their head around. Once you become more familiar with SQL Server, you may find yourself using SQL scripts to perform many of the tasks that you started out doing via the graphical user interface.

Next we’ll look at the query designer.

Понравилась статья? Поделить с друзьями:
  • Как написать скрипт space engineers
  • Как написать скрипт mt4
  • Как написать скрипт bash ubuntu
  • Как написать скринсейвер
  • Как написать скорпион