0.00
0 читателей, 18 топиков

Правильное выполнение транзакции в MSSQL

Два варианта выполнения транзакции в MSSQL, для которых при возникновении ошибки транзакция отменяется.

Первый вариант:
BEGIN TRY
    BEGIN TRAN
    UPDATE 1
    UPDATE 2 --Ошибка
    UPDATE 3
    COMMIT TRAN
END TRY
BEGIN CATCH
    ROLLBACK TRAN
END CATCH


Второй вариант:
SET XACT_ABORT ON
BEGIN TRAN
UPDATE 1
UPDATE 2 --Ошибка
UPDATE 3
COMMIT TRAN


Оба варианта сделают одно и то-же при возникновении ошибки на втором шаге, отменят всю транзакцию включая первый шаг.

MSSQL - Try Catch Transaction (Отменяем транзакцию с ошибкой корректно)

Ниже приведен пример корректного отмена транзакции при ошибке:
update Params set Value=168 where Param = 'SessionHoursLimit'

PRINT @@TRANCOUNT  
	BEGIN TRY
    BEGIN TRAN  
        PRINT @@TRANCOUNT  
		update Params set Value=167 where Param = 'SessionHoursLimit'
		select 1/0 -- Если закомментировать эту строку то предыдущая строка выполнится
    COMMIT  TRAN 
	END TRY
	BEGIN CATCH
		if @@TRANCOUNT>0
		ROLLBACK TRAN
	END CATCH
PRINT @@TRANCOUNT  

select * from Params


Если закомментировать строку с ошибочным оператором SELECT 1/0 то предшествующая строка будет выполнена и транзакция успешно завершится, если оставить строку SELECT 1/0 то транзакция отменится полностью, и параметр Value останется таким, каким он был установлен в первой строке скрипта до начала транзакции.

MSSQL - Выбор N пронумерованных виртуальных записей записей при помощи системной таблицы SPT_VALUES

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

Пример:
select number as Section from master..spt_values where type='L' and number>0 and number<=100


Пример выводит 100 строк таблицы с значениями от 1 до 100 и единственным столбцом Section.

MSSQL Оконные функции - Пример ROWNUMBER OVER PARTITION BY

Оконные функции — это такие функции которые на основе окна (набора записей) вычисляют скалярное (одиночное) значение. Это значение определяется с помощью инструкции OVER.

Пример:
select regioncode, aolevel, offname,
 rownumber() over(partition by regioncode order by aolevel, offname) as rownum
 from s_adr_fias
order by regioncode, aolevel, offname;


В данном примере будет сделана выборка в которой для каждого regioncode в поле rownum будет нумерация отсортированных значений aolevel, offname.

OFFSET FETCH пример применения в TSQL

Фильтр OFFSET FETCH в языке TSQL интересен тем что в отличии от фильтра TOP позволяет пропускать заданное количество строк ROWS.

Пример:
select regioncode, aolevel, offname from s_adr_fias
order by regioncode, aolevel, offname
offset 100 rows fetch next 50 rows only;


Данный пример демонстрирует выборку из набора отсортированного по условию ORDER BY (по полям regioncode, aolevel, offname) 50 строк данных пропустив первые 100 строк.

!!! Сначала выполняется именно сортировка, и только затем, из отсортированного набора данных берётся необходимый диапазон.

P.S. На больших объёмах, даже с учетом самой оптимальной индексации, данный фильтр является довольно ресурсоемким.

TSQL - Обновление одной таблицы с Join по второй (MSSQL - Update with join)

Пример обновления данных в одной таблице с одновременным сопоставлением и проверкой условия по второй таблице при помощи JOIN:
update cc
	set cc.ActivateState=2
 from ClientsCards cc
	left join ClientsCardsHeads cch 
 on cch.CardUid=cc.Uid
	where cc.ActivateState=0 and cch.State=3


ClientsCards cc — Первая таблица в которой производится изменение.

ClientsCardsHeads cch — Вторая таблица с данными которой производится сверка.

Чистка логов базы данных MSSQL

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

Сама проблема:
The transaction log for database 'база_данных' is full due to 'LOG_BACKUP'. 

Проблему разумеется надо решать.

И вот как это делается:

Для обрезки лога используется вот эта команда:
DBCC SHRINKFILE(база_данных_log, 100);

При выполнении этой команды, LOG файл будет обрезан до 100 мегабайт.

Смотреть дальше

Пример MERGE в MSSQL T-SQL

Простой пример MERGE для TSQL.

В примере подразумевается, что мы оперируем двумя одинаковыми по структуре таблицами (в реальной жизни это условие вовсе не обязательно).
Таблицы TargetTableи SourceTable — состоят всего из двух полей:
Id — некий идентификатор.
Name — Название объекта.

В примере ниже мы проверяем для всех записей из SourceTable — существует ли в таблице TargetTable запись с аналогичным Id и если существует, то меняем для этой записи поле Name в TargetTable, а если не существует то добавляем запись в TargetTable из SourceTable целиком.


MERGE TargetTable AS target  -- таблица которую будем менять, таблица приемник

USING (SELECT Id, Name FROM SourceTable) AS source 

ON (target.Id = source.Id)  -- условие по которому сопоставляем источник и приемник

WHEN MATCHED AND target.Name!=source.Name -- Если такой уже есть, то проверяем не совпадает ли Name и если не совпадает то меняем

    THEN UPDATE SET target.Name = source.Name -- обновляем

WHEN NOT MATCHED  -- если такого Id нет в таблице target то добавляем

    THEN INSERT VALUES(source.Id, source.Name) -- добавление записи


Вот и всё.

Установка русской кодировки на уже созданную базу данных (смена COLLATION)

Полезный пример изменения кодировки (COLLATION) на уже созданной базе данных.
В данном примере устанавливается русская кодировка: Cyrillic_General_CI_AS

USE master;
GO

-- Переводим БД в single-user mode
ALTER DATABASE [имя_базы_данных]
SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

-- Меняем кодировку COLLATION
ALTER DATABASE [имя_базы_данных]
COLLATE Cyrillic_General_CI_AS ;
GO

-- Переводим БД обратно в multi-user mode
ALTER DATABASE [имя_базы_данных]
SET MULTI_USER WITH ROLLBACK IMMEDIATE;
GO  
 
--Проверяем настройки COLLATION.
SELECT name, collation_name
FROM sys.databases
WHERE name = 'имя_базы_данных';
GO


Читать дальше →

Выборка длинных строк в MSSQL Manager

По умолчанию в MSSQL-Manager длинна строки в выборки ограничена, и при достаточно большом размере строки в выборку попадет только её часть, но есть способ обойти этот изъян.
Чтобы выбрать длинную строку, достаточно просто назначить имя на поле с названием [XML_F52E2B61-18A1-11d1-B105-00805F49916B].

Например:
select [Полк_с_длинным_varchar_max] as [XML_F52E2B61-18A1-11d1-B105-00805F49916B] from 
[dbo].[Таблица]