Программирование >>  Программирование баз данных 

1 ... 166 167 168 [ 169 ] 170 171 172 ... 346


using System;

using System.Data;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using Microsoft.SqlServer.Server;

[Serializable]

[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.Native)] public struct ExampleAggregate

public void InitO

В этом месте должен находиться пользовательский код

public void Accumulate(SqlString Value)

В этом месте должен находиться пользовательский код

public void Merge(ExampleAggregate Group)

В этом месте должен находиться пользовательский код

public SqlString Terminate()

В этом месте должен находиться пользовательский код return new SqlString( );

Это - вспомогательная переменная private int varl;

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

В этом разделе рассмотрим пример создания аналога агрегирующей функции PRODUCT, которая является такой же, как функция SUM, но в ней вместо сложения выполняется умножение. Как и в функции SUM, в функции PRODUCT будут игнорироваться NULL-значения (если же все сомножители представляют собой NULL-значения, то функция PRODUCT должна возвращать NULL-значение), но в случае появления в исходных данных NULL-значений будут вырабатываться предупреждающие сообщения для пользователя о том, что таковые значения обнаружены и проигнорированы.

Вначале нам необходимо внести некоторые простые модификации. Прежде всего присвоим классу имя Product вместо имени ExampleAggregate, присвоенного первоначально в связи с тем, что так был назван проект. Кроме того, необходимо объявить некоторые переменные-члены для хранения накапливаемого значения и значений некоторых флажков.

using System;

using System.Data;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using Microsoft.SqlServer.Server;

[Serializable]



[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.Native)] public struct Product

private SqlDouble dAccumulator; private bool fContainsNull; private bool fAllNull;

Переменная fContainsNull будет использоваться для получения информации о том, следует ли предупредить пользователя о том, что обнаружены какие-либо игнорируемые значения. Переменная fAllNull позволяет определить, что все полученные значения представляли собой NULL-значение; в этом случае предусмотрен возврат NULL-значения и в качестве результата.

Затем необходимо инициализировать значения применяемых переменных-членов в ходе выполнения метода Init: public void InitО

Инициализация флажков и накопительной переменной

dAccumulator = 1;

fContainsNull = false;

fAllNull = true;

Теперь мы можем создать основную накопительную функцию: public void Accumulate(SqlDouble Value)

Это - основной участок кода. В нем могут быть реализованы применяемые

алгоритмы вычислений. А в данном примере просто происходит умножение

текущего значения накопительной переменной на новое входное значение.

При обнаружении NULL-значения устанавливается флажок, указывающий на

то, что распознана ситуация, связанная с появлением неопределенного

значения. В результате этого полученные данные игнорируются и

сохраняется значение, накопленное к данному моменту

if (Value.IsNull) {

fContainsNull = true;

else {

fAllNull = false; dAccumulator *= Value;

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

На этом подготовка накопительной части функции полностью завершена, и мы можем заняться разработкой метода Merge, обеспечивающего объединение результатов, public void Merge(Product Group)

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



if (Group.dAccumulator.IsNull)

if (Group.fContainsNull) fContainsNull = true;

if (!Group.fAllNull) fAllNull = false;

dAccumulator *= dAccumulator;

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

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

public SqlDouble Terminate()

На этом вьшолнение работы заканчивается и происходит вывод результатов

if (fAllNull)

return SqlDouble.Null;

else {

SqlContext .Pipe. Send ( WARNING: Aggregate values exist and were ignored ); return dAccumulator;

Вслед за окончанием описанной выше процедуры разработки мы можем приступить к компиляции кода и его выгрузке: CREATE ASSEMBLY ExampleAggregate

FROM <solution path>\ExampleAggregate\bin\Debug\ExampleAggregate.dll

После этого можно создать агрегируюхцую функцию. След)ет отметить, что для создания агрегирующих функций применяется другой синтаксис. Основная синтаксическая структура оператора создания агрегирующих функций приведена ниже.

CREATE AGGREGATE [ <schema name> . ] <aggregate name>

(@param name <input sqltype> ) RETURNS <return sqltype>

EXTERNAL NAME <assembly name> [ .<class name> ]

Итак, чтобы создать агрегирующую функцию на основе разработанной сборки,

необходимо применить, допустим, такой оператор:

CREATE AGGREGATE dbo.Product(©input float) RETURNS float

EXTERNAL NAME ExampleAggregate.Product

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

CREATE TABLE ТеStAggregate (



1 ... 166 167 168 [ 169 ] 170 171 172 ... 346

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика