курсач / Наволоцкий_1302_v2
.pdf-- Логика: Если единицы измерения нет, возвращаем просто число
IF @Unit IS NULL OR @Unit = ''
SET @Result = @Value;
ELSE
SET @Result = @Value + ' ' + @Unit;
RETURN @Result;
END
GO
2.Встроенная табличная функция (Inline Table-Valued Function) — [Stock].[udf_GetComponentParams]
Возвращает набор технических параметров для конкретного компонента. В отличие от представлений, данная функция параметризована (принимает ID компонента), что позволяет получать данные точечно, снижая нагрузку на сервер.
Листинг реализации функции приведен ниже:
IF OBJECT_ID('[Stock].[udf_GetComponentParams]', 'IF') IS
NOT NULL DROP FUNCTION [Stock].[udf_GetComponentParams];
GO
CREATE FUNCTION [Stock].[udf_GetComponentParams]
(
@CompID INT
)
RETURNS TABLE
31
AS
RETURN
(
SELECT
ParamName AS [Parameter],
-- Вызов скалярной функции внутри табличной
[Stock].[udf_FormatValue](ParamValue, Unit) AS [ValueFormatted]
FROM [Stock].[ComponentParams]
WHERE ComponentID = @CompID
); GO
3.Многооператорная табличная функция (Multi-Statement Table-Valued Function) — [Stock].[udf_GetComponentQualityReport]
Реализует сложную аналитическую логику. Функция создает в памяти переменную-таблицу, наполняет её первичными данными, а затем выполняет серию операций обновления (UPDATE) для расчета рейтинга качества заполнения данных (Quality Score) по каждому компоненту.
Результатом работы функции является готовая таблица с вердиктом о полноте информации.
Листинг реализации функции приведен ниже:
IF OBJECT_ID('[Stock].[udf_GetComponentQualityReport]', 'TF') IS NOT NULL DROP FUNCTION [Stock].[udf_GetComponentQualityReport];
GO
CREATE FUNCTION [Stock].[udf_GetComponentQualityReport]
32
(
@CategoryID INT -- Фильтр по категории
)
RETURNS @ReportTable TABLE
(
PartNumber NVARCHAR(100),
Manufacturer NVARCHAR(100),
HasDescription BIT,
HasModel BIT,
QualityScore INT, -- Вычисляемый балл (0-100) Verdict NVARCHAR(50)
)
AS
BEGIN
-- 1. Первичная вставка данных
INSERT INTO @ReportTable (PartNumber, Manufacturer,
HasDescription, HasModel, QualityScore, Verdict)
SELECT c.PartNumber, m.Name,
CASE WHEN c.Description IS NOT NULL THEN 1 ELSE 0
END,
CASE WHEN EXISTS(SELECT 1 FROM [Stock].[ComponentModels] cm WHERE cm.ComponentID = c.ComponentID) THEN 1 ELSE 0 END,
0, -- Начальный балл
'Unknown'
FROM [Stock].[Components] c
33
JOIN [Ref].[Manufacturers] m ON c.ManufacturerID =
m.ManufacturerID
WHERE c.CategoryID = @CategoryID;
--2. Логика расчета баллов (Multi-step logic)
--+40 баллов, если есть описание
UPDATE @ReportTable SET QualityScore = QualityScore + 40 WHERE HasDescription = 1;
-- +60 баллов, если есть мат. модель
UPDATE @ReportTable SET QualityScore = QualityScore + 60 WHERE HasModel = 1;
-- 3. Вынесение вердикта
UPDATE @ReportTable
SET Verdict = CASE
WHEN QualityScore = 100 THEN 'Excellent'
WHEN QualityScore >= 40 THEN 'Good'
ELSE 'Poor Data'
END;
RETURN;
END
34
6.2. Представления (Views)
Представления используются для упрощения доступа к данным и формирования отчетов [5]. В проекте реализованы запросы различной сложности:
1. |
Сводный |
отчет — [Stock].[v_FullComponentReport] |
|||
|
Реализует классическое соединение (INNER JOIN) четырех таблиц для |
||||
|
отображения полной информации о компоненте с расшифровкой всех |
||||
|
справочных полей (производитель, категория, корпус). |
|
|||
2. |
Инженерный |
фильтр — [Stock].[v_ActiveComponentsSpiceready] |
|||
|
Предоставляет выборку только активных компонентов, имеющих |
||||
|
математическую модель SPICE. Используется для быстрой фильтрации |
||||
|
данных в инженерных подсистемах. |
|
|
||
3. |
Аналитическое |
представление — [Stock].[v_CategoryAnalytics] |
|||
|
Демонстрирует использование продвинутых конструкций SQL. Запрос |
||||
|
построен с применением обобщенных табличных выражений (CTE) для |
||||
|
предварительной |
агрегации |
данных. |
Также |
используется |
предложение HAVING для пост-фильтрации сгруппированных данных
и вычисления процента активных компонентов внутри каждой категории.
6.3. Хранимые процедуры и подсистема XML
Хранимые процедуры образуют основной интерфейс (API) для изменения данных, обеспечивая безопасность и целостность информации.
Прямой доступ к таблицам для пользователей закрыт.
|
Управление |
транзакциями |
и |
обработка |
ошибок. |
В |
процедурах |
модификации |
данных |
||
(usp_CreateComponent, usp_ImportComponentsFromXML) |
реализован |
||||
механизм явного управления транзакциями: |
|
|
|||
|
|
35 |
|
|
|
Все операции выполняются внутри блока BEGIN TRANSACTION ...
COMMIT.
Используется конструкция BEGIN TRY ... BEGIN CATCH для перехвата ошибок. В случае возникновения сбоя (например, нарушение уникальности или разрыв соединения) выполняется автоматический откат транзакции (ROLLBACK), что гарантирует атомарность операций: данные либо сохраняются полностью, либо не сохраняются вовсе.
Поиск и фильтрация.
Процедура [Stock].[usp_SearchComponents] реализует логику динамической фильтрации. Использование параметров по умолчанию (NULL) позволяет использовать одну процедуру для различных сценариев поиска: по артикулу,
по производителю или комбинированно. Также процедура генерирует временную метку выполнения запроса «на лету» средствами функции GETDATE().
Интеграция с внешними системами (XML).
Для обмена данными реализованы процедуры импорта и экспорта [8]:
Экспорт (usp_ExportReportToXML): Использует конструкцию FOR XML PATH для преобразования реляционных табличных данных в иерархический XML-формат.
Импорт (usp_ImportComponentsFromXML): Выполняет разбор входящего XML-документа с помощью метода .nodes(). Процедура автоматически сопоставляет текстовые названия из файла с числовыми идентификаторами справочников (Look-up), обеспечивая корректную загрузку данных даже из внешних источников, не знающих о внутренней структуре ID базы данных.
На рисунке 3 показан получившийся xml-файл в среде ms service
36
Рисунок 3 – Получившийся xml-документ
Этот документ можно открыть в ms excel и удобно просматривать таблицу.
Сконвертированный xml-файл, открытый через ms excel показан на рисунке 4.
Рисунок 4 – сконвертированный xml-файл, открытый через ms excel
37
7. СТРАТЕГИЯ РЕЗЕРВНОГО КОПИРОВАНИЯ
Для обеспечения сохранности данных и возможности восстановления системы после аппаратных сбоев или ошибок оператора была разработана стратегия резервного копирования (Backup Strategy) [9].
1. Выбор модели резервного копирования
В проекте реализована модель «Ежедневное полное резервное копирование с перезаписью» (Daily Full Backup with Overwrite).
Обоснование: Учитывая небольшой объем справочной базы данных и низкую частоту транзакций в ночное время, полное копирование является наиболее надежным и простым в восстановлении способом.
Параметр WITH INIT: Используется при создании бэкапа для перезаписи файла. Это позволяет всегда иметь на диске одну актуальную копию базы данных, предотвращая бесконечный рост размера файла резервной копии и экономя дисковое пространство.
2. Автоматизация (Решение для SQL Server Express)
Поскольку используемая редакция СУБД (Express Edition) не содержит встроенного планировщика заданий «SQL Server Agent», компоненты автоматизации были реализованы средствами операционной системы.
Исполняемый компонент (AutoBackup.bat): Разработан пакетный файл,
содержащий команду вызова утилиты sqlcmd. Скрипт подключается к серверу в режиме доверительного соединения Windows (-E) и выполняет
T-SQL команду BACKUP DATABASE.
o Текст |
|
|
скрипта: |
sqlcmd -S .\SQLEXPRESS -E -Q "BACKUP DATABASE CircuitDB |
|||
TO DISK='...' WITH INIT" |
|
|
|
Планировщик |
(Scheduler): Для регулярного |
запуска |
скрипта |
использован |
«Планировщик заданий Windows» |
(Task |
Scheduler). |
|
38 |
|
|
Настроена задача Backup CircuitDB, которая автоматически запускает файл AutoBackup.bat ежедневно в 03:00 (период минимальной нагрузки на сервер).
Рисунок 5 – Настройка автоматического резервного копирования
В дополнение к автоматической системе, в скрипте администрирования
(05_SecurityAndAdmin.sql) предусмотрен блок кода для выполнения резервного копирования вручную администратором через среду SSMS.
/* =============================================
ЧАСТЬ 4: СТРАТЕГИЯ РЕЗЕРВНОГО КОПИРОВАНИЯ Скрипт создает бэкап с ДАТОЙ в имени файла.
============================================= */ PRINT 'Выполнение резервного копирования... ' + CONVERT(VARCHAR(30), GETDATE(), 120);
GO
DECLARE @BackupName NVARCHAR(255);
DECLARE @BackupFile NVARCHAR(255);
39
DECLARE @CurrentDate NVARCHAR(20);
--Формируем строку даты вручную для SQL 2012 (YYYYMMDD_HHmm)
SET @CurrentDate = CONVERT(VARCHAR(8), GETDATE(), 112) + '_' + REPLACE(CONVERT(VARCHAR(5), GETDATE(), 108), ':', '');
--Путь к папке Backup (Стандартный для SQL Express)
SET @BackupFile = N'C:\Program Files (x86)\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\Backup\CircuitDB_' + @CurrentDate + '.bak';
SET @BackupName = N'CircuitDB-Full Database Backup';
-- Выполняем бэкап
BACKUP DATABASE [CircuitDB]
TO DISK = @BackupFile
WITH NOFORMAT, NOINIT,
NAME = @BackupName,
SKIP, NOREWIND, NOUNLOAD, STATS = 10;
PRINT 'Бэкап сохранен в: ' + @BackupFile;
GO
На рисунке 6 показан результат успешного выполнения запроса бэкапа базы
40
