Отказоустойчивая кластеризация в windows server

Усечение журнала транзакцийTransaction Log Truncation

Процесс усечения журнала освобождает место в файле журнала для повторного использования журналом транзакций.Log truncation frees space in the log file for reuse by the transaction log. Усечение журнала необходимо для предотвращения переполнения журнала.Log truncation is essential to keep the log from filling. При усечении журнала удаляются неактивные виртуальные файлы журнала из логического журнала транзакций базы данных SQL ServerSQL Server , что приводит к освобождению пространства в логическом журнале для повторного использования физическим журналом транзакций.Log truncation deletes inactive virtual log files from the logical transaction log of a SQL ServerSQL Server database, freeing space in the logical log for reuse by the Physical transaction log. Если усечение журнала транзакций не выполняется, со временем он заполняет все доступное место на диске, отведенное для файлов физического журнала.If a transaction log were never truncated, it would eventually fill all the disk space that is allocated to its physical log files.

В целях предотвращения этой проблемы усечение журнала выполняется автоматически после следующих событий, за исключением тех случаев, когда оно по каким-то причинам задерживается.To avoid this problem, unless log truncation is being delayed for some reason, truncation occurs automatically after the following events:

  • В простой модели восстановления — после достижения контрольной точки.Under the simple recovery model, after a checkpoint.

  • Для моделей полного восстановления и моделей восстановления с неполным протоколированием, если контрольная точка была создана после предыдущего резервного копирования, усечение происходит после резервного копирования журнала (если только это не резервная копия журнала только для копирования).Under the full recovery model or bulk-logged recovery model, if a checkpoint has occurred since the previous backup, truncation occurs after a log backup (unless it is a copy-only log backup).

Дополнительные сведения см. в подразделе далее в этой статье.For more information, see , later in this topic.

Примечание

Усечение журнала не приводит к уменьшению размера физического файла журнала.Log truncation does not reduce the size of the physical log file. Для уменьшения реального размера физического файла журнала необходимо выполнить его сжатие.To reduce the physical size of a physical log file, you need to shrink the log file. Сведения о сжатии физического файла журнала см. в разделе Управление размером файла журнала транзакций.For information about shrinking the size of the physical log file, see Manage the Size of the Transaction Log File.

Различия между инструкциями RAISERROR и THROWDifferences Between RAISERROR and THROW

В следующей таблице приведены некоторые различия между инструкциями RAISERROR и THROW.The following table lists differences between the RAISERROR and THROW statements.

RAISERROR, инструкцияRAISERROR statement Инструкция THROWTHROW statement
Если инструкции RAISERROR передается параметр msg_id, то идентификатор должен быть задан в sys.messages.If a msg_id is passed to RAISERROR, the ID must be defined in sys.messages. Параметр error_number не требуется определять в sys.messages.The error_number parameter does not have to be defined in sys.messages.
Параметр msg_str может содержать стили форматирования printf.The msg_str parameter can contain printf formatting styles. Параметр message не принимает форматирование стиля printf.The message parameter does not accept printf style formatting.
Параметр severity указывает серьезность исключения.The severity parameter specifies the severity of the exception. Параметр severity отсутствует.There is no severity parameter. Серьезности исключения всегда задается значение 16.The exception severity is always set to 16.

PL/SQL exception categories

PL/SQL has three exception categories:

  • Internally defined exceptions are errors which arise from the Oracle Database environment. The runtime system raises the internally defined exceptions automatically. ORA-27102 (out of memory) is one example of Internally defined exceptions. Note that Internally defined exceptions do not have names, but an error code.
  • Predefined exceptions are errors which occur during the execution of the program. The predefined exceptions are internally defined exceptions that PL/SQL has given names e.g., , .
  • User-defined exceptions are custom exception defined by users like you. User-defined exceptions must be raised explicitly.

The following table illustrates the differences between exception categories.

Category Definer Has Error Code Has Name Raised Implicitly Raised Explicitly
Internally defined Runtime system Always Only if you assign one Yes Optionally
Predefined Runtime system Always Always Yes Optionally
User-defined User Only if you assign one Always No Always

In this tutorial, you have learned about the PL/SQL exceptions and how to write exception handlers to handle the possible exceptions in a block.

  • Was this tutorial helpful?

RemarksRemarks

Результаты функции @@VERSION представлены как одна строка типа nvarchar.The @@VERSION results are presented as one nvarchar string. Для получения значений отдельных свойств можно использовать функцию SERVERPROPERTY (Transact-SQL).You can use the SERVERPROPERTY (Transact-SQL) function to retrieve the individual property values.

Для SQL ServerSQL Server возвращаются следующие сведения.For SQL ServerSQL Server, the following information is returned.

  • SQL ServerSQL Server versionversion

  • Архитектура процессораProcessor architecture

  • Дата сборки SQL ServerSQL ServerSQL ServerSQL Server build date

  • Заявление об авторских правахCopyright statement

  • SQL ServerSQL Server editionedition

  • Версия операционной системыOperating system version

Для База данных SQL AzureAzure SQL Database возвращаются следующие сведения.For База данных SQL AzureAzure SQL Database, the following information is returned.

  • Выпуск — «Microsoft SQL Azure»Edition- «Microsoft SQL Azure»

  • Уровень продукта — «(RTM)»Product level- «(RTM)»

  • Версия продуктаProduct version

  • Дата сборкиBuild date

  • Заявление об авторских правахCopyright statement

Примечание

Нам известно о проблеме, когда @@VERSION сообщает о неправильной версии продукта для базы данных SQL Azure.We are aware of an issue where the product version reported by @@VERSION is incorrect for Azure SQL Database. Версия ядра базы данных SQL Server, выполняющаяся в базе данных SQL Azure, всегда выше локальной версии SQL Server и содержит последние исправления безопасности.The version of the SQL Server database engine run by Azure SQL Database is always ahead of the on-premises version of SQL Server, and includes the latest security fixes. Это означает, что уровень исправления всегда совпадает с локальной версией SQL Server или выше ее, и что последние функции, доступные в SQL Server, также доступны в базе данных SQL Azure.This means that the patch level is always on par with or ahead of the on-premises version of SQL Server, and that the latest features available in SQL Server are available in Azure SQL Database.

Чтобы определить выпуск ядра базы данных программным способом, используйте SELECT SERVERPROPERTY(‘EngineEdition’).To programmatically determine the engine edition, use SELECT SERVERPROPERTY(‘EngineEdition’). Этот запрос вернет «5» для отдельных баз данных или эластичных пулов и «8» для управляемых экземпляров в Базе данных SQL Azure.This query will return ‘5’ for single databases/elastic pools and ‘8’ for managed instances in Azure SQL Database.

После решения этой проблемы документация будет обновлена.We will update the documentation once this issue is resolved.

Обработка исключений во вложенных блоках

Если вложенный блок обрабатывает исключение, он завершается
без ошибок и управление передается во внешний блок оператору, следующему за
оператором END вложенного блока.

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

Если ни в одном из внешних блоков не будет найден подходящий
обработчик исключения, исключение распространяется в вызывающую среду. Каждая
вызывающая среда имеет собственные средства для показа ошибок. Например, SQL*Plus выдает на экран номер
необработанного исключения и соответствующее сообщение.

SQL> DECLARE

  2     v_error_code NUMBER;

  3     v_error_text
VARCHAR2(100);

  4     v_sal emp.sal%TYPE;

  5  BEGIN

  6     SELECT sal INTO v_sal FROM
emp WHERE LOWER(job)=LOWER(:v_job);

  7    
DBMS_OUTPUT.put_line(‘Salary of ‘ || :v_job || ‘ is ‘ || TO_CHAR(v_sal));

  8  END;

  9  /

DECLARE

ERROR at line 1:

ORA-01403: no data found

ORA-06512:
at line 6

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

EXCEPTION

   WHEN OTHERS THEN

      BEGIN

         операторы;

      EXCEPTION

         WHEN OTHERS THEN

            NULL;

      END;

END;

Именованные блоки PL/SQL

Именованные блоки PL/SQL называются программными
единицами
. Программные единицы делятся на три категории:

§  Процедуры,
позволяющие задавать параметры и выполняющие заданные действия

§  Функции,
позволяющие задавать параметры, вычисляющие и возвращающие значения

§  Пакеты,
объединяющие логически связанные процедуры и функции

Программные единицы
подразделяются на хранимые и прикладные подпрограммы (подпрограммы приложения):

Функции для перехвата ошибок

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

· 
SQLCODE – возвращает числовое значение
кода ошибки

— 
0 – исключений не было

— 
1 – пользовательское исключение

— 
+100 – исключение NO_DATA_FOUND

— 
отрицательное целое – номер ошибки сервера Oracle

· 
SQLERRM – возвращает сообщение, связанное
с кодом ошибки

Почти все коды исключений сервера Oracle имеют
отрицательное значение, кроме NO_DATA_FOUND, код
которого +100. Это происходит потому, что в соответствии со стандартом ANSI, если строка не найдена значение SQLCODE
должно быть равно +100.

SQL> VARIABLE v_job
VARCHAR2(20);

SQL>
EXECUTE :v_job := ‘Engineer’

PL/SQL
procedure successfully completed.

SQL> DECLARE

  2     v_error_code NUMBER;

  3     v_error_text
VARCHAR2(100);

  4     v_sal emp.sal%TYPE;

  5  BEGIN

  6     SELECT sal INTO v_sal FROM
emp WHERE LOWER(job)=LOWER(:v_job);

  7    
DBMS_OUTPUT.put_line(‘Salary of ‘ || :v_job || ‘ is ‘ || TO_CHAR(v_sal));

  8  EXCEPTION

  9     WHEN OTHERS THEN

 10        v_error_code :=
SQLCODE;

 11        v_error_text :=
SQLERRM;

 12       
DBMS_OUTPUT.put_line(TO_CHAR(v_error_code) || ‘ — ‘ || v_error_text);

 13  END;

 14  /

100 —
ORA-01403: no data found

PL/SQL
procedure successfully completed.

PL/SQL exception examples

Let’s take some examples of handling exceptions.

PL/SQL exception example

The following block accepts a customer id as an input and returns the customer name :

1
2
3
4
5
6
7
8
9
10
11
12
13
14

DECLARE

l_namecustomers.NAME%TYPE;

l_customer_idcustomers.customer_id%TYPE:=&customer_id;

BEGIN

— get the customer name by id

SELECTnameINTOl_name

FROMcustomers

WHEREcustomer_id=l_customer_id;
 

— show the customer name  

dbms_output.put_line(‘Customer name is ‘||l_name);

END;

If you execute the block and enter the customer id as zero, Oracle will issue the following error:

1 ORA-01403:nodatafound

The is a predefined exception.

Note that the following line does not execute at all because control transferred to the exception handling section.

1 dbms_output.put_line(‘Customer name is ‘||l_name);

To issue a more meaningful message, you can add an exception-handling section as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

DECLARE

l_namecustomers.NAME%TYPE;

l_customer_idcustomers.customer_id%TYPE:=&customer_id;

BEGIN

— get the customer

SELECTNAMEINTOl_name

FROMcustomers

WHEREcustomer_id=l_customer_id;

— show the customer name  

dbms_output.put_line(‘customer name is ‘||l_name);
 

EXCEPTION

WHENNO_DATA_FOUNDTHEN

dbms_output.put_line(‘Customer ‘||l_customer_id||’ does not exist’);

END;

If you execute this code block and enter the customer id 0, you will get the following message:

1 Customer0doesnotexist

PL/SQL exception example

First, modify the code block in the above example as follows and execute it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

DECLARE

l_namecustomers.name%TYPE;

l_customer_idcustomers.customer_id%TYPE:=&customer_id;

BEGIN

— get the customer

SELECTnameINTOl_name

FROMcustomers

WHEREcustomer_id=l_customer_id;

— show the customer name  

dbms_output.put_line(‘Customer name is ‘||l_name);
 

EXCEPTION

WHENNO_DATA_FOUNDTHEN

dbms_output.put_line(‘Customer ‘||l_customer_id||’ does not exist’);

END;

Second, enter the customer id 10 and you’ll get the following error:

1 ORA-01422:exactfetchreturnsmorethanrequestednumberofrows

This is another exception called which was not handled by the code.

Third, add the exception handler for the exception:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

DECLARE

l_namecustomers.NAME%TYPE;

l_customer_idcustomers.customer_id%TYPE:=&customer_id;

BEGIN

— get the customer

SELECTNAMEINTOl_name

FROMcustomers

WHEREcustomer_id>l_customer_id;

— show the customer name  

dbms_output.put_line(‘Customer name is ‘||l_name);

EXCEPTION

WHENNO_DATA_FOUNDTHEN

dbms_output.put_line(‘Customer ‘||l_customer_id||’ does not exist’);

WHENTOO_MANY_ROWSTHEN

dbms_output.put_line(‘The database returns more than one customer’);

END;

Finally, if you execute the code, enter 10 as the customer id. You will see that the code will not raise any exception and issue the following message:

1 Thedatabasereturnsmorethanonecustomer

Параметры в процедурах

Последнее обновление: 14.08.2017

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

Например, пусть в базе данных будет следующая таблица Products:

USE productsdb;
CREATE TABLE Products
(
    Id INT IDENTITY PRIMARY KEY,
    ProductName NVARCHAR(30) NOT NULL,
    Manufacturer NVARCHAR(20) NOT NULL,
    ProductCount INT DEFAULT 0,
    Price MONEY NOT NULL
);

Определим процедуру, которая будет добавлять данные в эту таблицу:

USE productsdb;
GO
CREATE PROCEDURE AddProduct
	@name NVARCHAR(20),
	@manufacturer NVARCHAR(20),
	@count INT,
	@price MONEY
AS
INSERT INTO Products(ProductName, Manufacturer, ProductCount, Price) 
VALUES(@name, @manufacturer, @count, @price)

После названия процедуры идет список входных параметров, которые определяются также как и переменные — название начинается с символа @,
а после названия идет тип переменной. И с помощью команды INSERT значения этих параметров будут передаваться в таблицу Products.

Используем эту процедуру:

USE productsdb;

DECLARE @prodName NVARCHAR(20), @company NVARCHAR(20);
DECLARE @prodCount INT, @price MONEY
SET @prodName = 'Galaxy C7'
SET @company = 'Samsung'
SET @price = 22000
SET @prodCount = 5

EXEC AddProduct @prodName, @company, @prodCount, @price

SELECT * FROM Products

Здесь передаваемые в процедуру значения определяются через переменные. При вызове процедуры ей через запятую передаются значения.
При этом значения передаются параметрам процедуры по позиции. Так как первым определен параметр @name, то ему будет передаваться первое значение — значение переменной @prodName.
Второму параметру — @manufacturer передается второе значение — значение переменной @company и так далее.
Главное, чтобы между передаваемыми значениями и параметрами процедуры было соответствие по типу данных.

Также можно было бы передать непосредственно значения:

EXEC AddProduct 'Galaxy C7', 'Samsung', 5, 22000

Также значения параметрам процедуры можно передавать по имени:

USE productsdb;

DECLARE @prodName NVARCHAR(20), @company NVARCHAR(20);
SET @prodName = 'Honor 9'
SET @company = 'Huawei'

EXEC AddProduct @name = @prodName, 
				@manufacturer=@company,
				@count = 3, 
				@price = 18000

При передаче параметров по имени параметру процедуры присваивается некоторое значение.

Необязательные параметры

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

USE productsdb;
GO
CREATE PROCEDURE AddProductWithOptionalCount
	@name NVARCHAR(20),
	@manufacturer NVARCHAR(20),
	@price MONEY,
	@count INT = 1
AS
INSERT INTO Products(ProductName, Manufacturer, ProductCount, Price) 
VALUES(@name, @manufacturer, @count, @price)

При этом необязательные параметры лучше помещать в конце списка параметров процедуры.

DECLARE @prodName NVARCHAR(20), @company NVARCHAR(20), @price MONEY
SET @prodName = 'Redmi Note 5A'
SET @company = 'Xiaomi'
SET @price = 22000

EXEC AddProductWithOptionalCount @prodName, @company, @price

SELECT * FROM Products

И в этом случае для параметра @count в процедуру можно не передавать значение.

НазадВперед

Описание

SQL оператор EXCEPT используется для возврата всех строк в первом операторе SELECT, которые не возвращаются вторым оператором SELECT. Каждый оператор SELECT будет определять набор данных. Оператор EXCEPT извлечет все записи из первого набора данных, а затем удалит из результатов все записи из второго набора данных.

Запрос Except

Пояснение: Запрос EXCEPT вернет записи в синей заштрихованной области. Это записи, которые существуют в наборе данных SELECT1, а не в наборе данных SELECT2.

Каждый оператор SELECT в запросе EXCEPT должен иметь одинаковое количество полей в наборах результатов с одинаковыми типами данных.

Подсказка: оператор EXCEPT поддерживается не во всех базах данных SQL. Он может использоваться в таких базах данных, как SQL Server, PostgreSQL и SQLite.

Для таких баз данных, как Oracle, используйте оператор MINUS для выполнения этого типа запроса.

ОбъяснениеExplanation

Пользователь попытался выполнить вход с учетными данными, правильность которых нельзя проверить.The user attempted to login with credentials that cannot be validated. Возможные причины.Possible causes are:

  • Имя входа может быть именем входа SQL ServerSQL Server, но сервер допускает только проверку подлинности Windows.The login may be a SQL ServerSQL Server login but the server only accepts Windows Authentication.

  • Попытка подключения с использованием проверки подлинности SQL ServerSQL Server, но использованное имя входа не существует в SQL ServerSQL Server.You are trying to connect using SQL ServerSQL Server Authentication but the login used does not exist on SQL ServerSQL Server.

  • Процедура входа может использовать проверку подлинности Windows, но имя входа — неопознанный участник Windows.The login may use Windows Authentication but the login is an unrecognized Windows principal. Неопознанный участник Windows означает, что имя входа не может быть проверено Windows.An unrecognized Windows principal means that the login cannot be verified by Windows. Причина может быть в том, что имя входа Windows принадлежит домену, который не является доверенным.This could be because the Windows login is from an untrusted domain.

Аналогичные неполадки могут вызвать менее определенную ошибку 18456.Similar problems can cause the less-specific error 18456.

RemarksRemarks

В инструкции, выполняемой до инструкции THROW, должен использоваться признак конца инструкции — точка с запятой (;).The statement before the THROW statement must be followed by the semicolon (;) statement terminator.

Если конструкция TRY…CATCH недоступна, то пакет инструкций завершается.If a TRY…CATCH construct is not available, the statement batch is terminated. Задаются номер строки и процедура, где вызывается исключение.The line number and procedure where the exception is raised are set. Серьезности задается значение 16.The severity is set to 16.

Если инструкция THROW указана без параметров, то она должна находиться внутри блока CATCH.If the THROW statement is specified without parameters, it must appear inside a CATCH block. Результатом этого будет вызов возникшего исключения.This causes the caught exception to be raised. Любая ошибка, возникающая в инструкции THROW, приводит к завершению пакета инструкций.Any error that occurs in a THROW statement causes the statement batch to be terminated.

% является зарезервированным символом в тексте сообщения инструкции THROW, и его необходимо экранировать.% is a reserved character in the message text of a THROW statement and must be escaped. Дважды укажите знак %, чтобы получить % в тексте сообщения, например: «Увеличение превышает 15 %% исходного значения.»Double the % character to return % as part of the message text, for example ‘The increase exceeded 15%% of the original value.’

RemarksRemarks

Полнотекстовые предикаты и функции работают в одной таблице, что следует из наличия предиката FROM.Full-text predicates and functions work on a single table, which is implied in the FROM predicate. Для поиска в нескольких таблицах используйте в предложении FROM соединенную таблицу, чтобы выполнять поиск в результирующем наборе, который получен в результате соединения нескольких таблиц.To search on multiple tables, use a joined table in your FROM clause to search on a result set that is the product of two or more tables.

Возвращаемая таблица содержит столбец с именем Key , содержащий значения полнотекстовых ключей.The table returned has a column named KEY that contains full-text key values. Каждая таблица с полнотекстовым индексом содержит столбец, значения которого гарантированно уникальны, а значения, возвращаемые в ключевом столбце, являются значениями полнотекстового ключа строк, соответствующих условию выбора, указанному в условии поиска CONTAINS.Each full-text indexed table has a column whose values are guaranteed to be unique, and the values returned in the KEY column are the full-text key values of the rows that match the selection criteria specified in the contains search condition. Свойство TableFulltextKeyColumn , полученное из функции OBJECTPROPERTYEX, предоставляет идентификатор этого уникального ключевого столбца.The TableFulltextKeyColumn property, obtained from the OBJECTPROPERTYEX function, provides the identity of this unique key column. Чтобы получить идентификатор столбца, связанного с полнотекстовым ключом полнотекстового индекса, используйте представление sys. fulltext_indexes.To obtain the ID of the column associated with the full-text key of the full-text index, use sys.fulltext_indexes. Дополнительные сведения см. в разделе sys. fulltext_indexes ()Transact-SQL .For more information, see sys.fulltext_indexes (Transact-SQL).

Чтобы получить нужные строки первоначальной таблицы, следует указать соединение со строками, возвращаемыми функцией CONTAINSTABLE.To obtain the rows you want from the original table, specify a join with the CONTAINSTABLE rows. Обычно используется следующая форма инструкции SELECT с предложением FROM и функцией CONTAINSTABLE:The typical form of the FROM clause for a SELECT statement using CONTAINSTABLE is:

Таблица, созданная функцией CONTAINSTABLE, включает столбец с именем Rank.The table produced by CONTAINSTABLE includes a column named RANK. Столбец Rank — это значение (от 0 до 1000) для каждой строки, показывающее, насколько хорошо строка соответствует критериям выбора.The RANK column is a value (from 0 through 1000) for each row indicating how well a row matched the selection criteria. Это значение обычно используется в инструкции SELECT следующим образом.This rank value is typically used in one of these ways in the SELECT statement:

  • В предложении ORDER BY для упорядочивания строк таблицы по рангу.In the ORDER BY clause to return the highest-ranking rows as the first rows in the table.

  • В списке выборки для определения ранжирующего значения каждой строки.In the select list to see the rank value assigned to each row.

АргументыArguments

expressionexpressionЧисловое выражение, определяющее количество возвращаемых строк.The numeric expression that specifies the number of rows to be returned. Если значение expression указано в процентах, оно неявно преобразуется в формат float.expression is implicitly converted to a float value if you specify PERCENT. В противном случае expression преобразуется в формат bigint.Otherwise, expression is converted to bigint.

PERCENTPERCENTУказывает на то, что запрос возвращает только первые expression процентов строк из результирующего набора.Indicates that the query returns only the first expression percent of rows from the result set. Дробные значения округляются до следующего целого числа.Fractional values are rounded up to the next integer value.

WITH TIESWITH TIESВозвращает две или более строки, которые соперничают за последнее место в ограниченном результирующем наборе.Returns two or more rows that tie for last place in the limited results set. Этот аргумент можно использовать только с предложением ORDER BY.You must use this argument with the ORDER BY clause. В режиме WITH TIES количество возвращаемых строк может превысить значение expression.WITH TIES might cause more rows to be returned than the value specified in expression. Например, если expression имеет значение 5 и существуют еще 2 строки с такими же значениями столбцов, указанных в предложении ORDER BY, что и у пятой строки, результирующий набор будет содержать 7 строк.For example, if expression is set to 5 but two additional rows match the values of the ORDER BY columns in row 5, the result set will contain seven rows.

Предложение TOP можно сочетать с аргументом WITH TIES только в инструкциях SELECT, и только если вместе с ними задано предложение ORDER BY.You can specify the TOP clause with the WITH TIES argument only in SELECT statements, and only if you’ve also specified the ORDER BY clause. Порядок возврата связанных записей произволен.The returned order of tying records is arbitrary. ORDER BY не влияет на это правило.ORDER BY doesn’t affect this rule.

Расширения SQL Server для группировки

Последнее обновление: 19.07.2017

Дополнительно к стандартным операторам GROUP BY и HAVING SQL Server поддерживает еще четыре специальных расширения для группировки данных:
ROLLUP, CUBE, GROUPING SETS и OVER.

ROLLUP

Оператор ROLLUP добавляет суммирующую строку в результирующий набор:

SELECT Manufacturer, COUNT(*) AS Models, SUM(ProductCount) AS Units
FROM Products
GROUP BY Manufacturer WITH ROLLUP

Как видно из скриншота, в конце таблицы была добавлена дополнительная строка, которая суммирует значение столбцов.

Альтернативный синтаксис запроса, который можно использовать, начиная с версии MS SQL Server 2008:

SELECT Manufacturer, COUNT(*) AS Models, SUM(ProductCount) AS Units
FROM Products
GROUP BY ROLLUP(Manufacturer)

При группировке по нескольким критериям ROLLUP будет создавать суммирующую строку для каждой из подгрупп:

SELECT Manufacturer, COUNT(*) AS Models, SUM(ProductCount) AS Units
FROM Products
GROUP BY Manufacturer, ProductCount WITH ROLLUP

При сортировке с помощью ORDER BY следует учитывать, что она применяется уже после добавления суммирующей строки.

CUBE

CUBE похож на ROLLUP за тем исключением, что CUBE добавляет суммирующие строки для каждой комбинации групп.

SELECT Manufacturer, COUNT(*) AS Models, SUM(ProductCount) AS Units
FROM Products
GROUP BY Manufacturer, ProductCount WITH CUBE

GROUPING SETS

Оператор GROUPING SETS аналогично ROLLUP и CUBE добавляет суммирующую строку для групп. Но при этом он не включает сами группам:

SELECT Manufacturer, COUNT(*) AS Models, ProductCount
FROM Products
GROUP BY GROUPING SETS(Manufacturer, ProductCount)

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

SELECT Manufacturer, COUNT(*) AS Models, 
		ProductCount, SUM(ProductCount) AS Units
FROM Products
GROUP BY GROUPING SETS(ROLLUP(Manufacturer), ProductCount)

С помощью скобок можно определить более сложные сценарии группировки:

SELECT Manufacturer, COUNT(*) AS Models, 
		ProductCount, SUM(ProductCount) AS Units
FROM Products
GROUP BY GROUPING SETS((Manufacturer, ProductCount), ProductCount)

OVER

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

SELECT ProductName, Manufacturer, ProductCount,
		COUNT(*) OVER (PARTITION BY Manufacturer) AS Models,
		SUM(ProductCount) OVER (PARTITION BY Manufacturer) AS Units
FROM Products

Выражение OVER ставится после агрегатной функции, затем в скобках идет выражение PARTITION BY и столбец,
по которому выполняется группировка.

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

НазадВперед

Ссылка на основную публикацию