|
Программирование >> Программирование баз данных
щиеся к текущему каталогу. В ходе циклической обработки происходит заполнение массива данными, полученными путем определения свойств FullName и LastWriteTime каждого очередного файла: private static void GetFiles(string d, string sWildCard, ArrayList aPileArray) foreach (string f in Directory.GetFiles(d, sWildCard)) Filelnfo fi = new Filelnfo(f); object [] colunrn = new object [2]; colunm[0] = f i. FullName ; column[1] = fi.LastWriteTime; aFileArray.Add(column); Ha основании полученных данных мы можем приступить к окончательному решению поставленной задачи путем фактической реализации функции FillRow, назначение которой сводится к обеспечению связи между массивом и внешним миром; иными словами, эта функция обеспечивает построчную передачу данных. private static void FillRow (Object ob j, out string filename, out DateTime date) object [] row = (object []) obj ; filename = (string)row[0]; date = (DateTime)row[1]; После завершения описанньгх подготовительных действий мы можем начать компиляцию и выгрузку сборки. Для этого используется та же команда CREATE ASSEMBLY, к которой мы обращались на протяжении всей главы, но с небольшим дополнением - необходимо объявить сборку как имеющую заданное право доступа EXTERNAL ACCESS. Чтобы у нас была возможность применять такое объявление, необходимо выполнить одно из двух условий, описанных ниже. Сборка должна быть подписана с помощью сертификата, который соответствует пользователю с надлежащими правами EXTERNAL ACCESS (дополнительная информация по этой теме приведена в главе 22). Владелец базы данных имеет права EXTERNAL ACCESS, и база данньгх отмечена как TRUSTWORTHY (заслуживающая доверия) в свойствах базы данных. По условиям рассматриваемого примера не предусмотрено применение подписанной сборки, поэтому мы должны обеспечить, чтобы применяемая база данных была отмечена как заслуживающая доверия: ALTER DATABASE AdventureWorks SET TRUSTWORTHY ON После этого мы получаем возможность завершить выгрузку сборки с надлежащими правами дост)Т1а: USE AdventureWorks CREATE ASSEMBLY fExampleTVF FROM <solution path>\ExampleTVF\bin\Debug\ExampleTVF.dll WITH PERMISSION SET = EXTERNAL. ACCESS Фактически задача создания ссылки на функцию, в которой используется созданная нами сборка, не слишком затруднительна, но становится немного сложнее по сравнению с задачей создания ссылки на простую скалярную функцию. Дело в том, что кроме входных параметров, мы должны определить возвращаемую таблицу: CREATE FUNCTION fTVFExample ( ©RootDir nvarchar(max), ©Wildcard nvarchar(max), ©IncludeSubDirs bit RETURNS TABLE ( FileName nvarchar(max), LastWriteTime nvarchar(max) AS EXTERNAL NAME ExampleTVF.UserDefinedFunctions. DirectoryList И с этого момента подготовка к проверке завершена: SELECT FileName, LastWriteTime FROM dbo.fTVFExample сел-, * . sys , 0) Полученные результаты в определенной степени завися г от того, какие компоненты и примеры установлены в конкретной системе, но, вообще говоря, должны выглядеть примерно так: FileName LastWriteTime C:\CONFIG.SYS 2006-04-01 00:21:43.470 C:\I0.SYS 2006-04-01 00:21:43.470 C:\MSDOS.SYS 2006-04-01 00:21:43.470 C:\pagefile.sys 2006-05-02 20:08:56.500 (4 row(s) affected) Итак, в этом разделе было показано не только то, как можно создать табличную функцию, но и как получить доступ к внешним данным, а это открывает перед разработчиками весьма значительные возможности! Создание агрегирующих функций Тематика создания агрегирующих функций действительно является тем новым, что вносит инфраструктура .NET, рассматриваемая в данной главе, по сравнению с другими средствами SQL Server. Безусловно, в связи с внедрением инфраструктуры .NET значительные усовершенствования были достигнуты и в области применения определяемых пользователем типов данных, о которых речь пойдет немного позже, но агрегирующие функции представляют собой нечто, не осуществршое другими способами, поскольку пользовательские функции, предусмотренные в языке T-SQL, не обеспечивают агрегирование. Рассмотрим определение понятия агрегирующей ф\тнкции. Прежде всего отметим, что к категории агрегирующих функций относятся функции SUM, AVG, MIN и MAX. Эти функции обрабатывают определенный набор данных, а затем возвращают значение, полученное по результатам определеьшого анализа всего этого набора. Данные, полученные с помощью агрегирующей функции, могуг быть основаны на всем результирующем наборе или получены с учетом каких-то критериев, заданных в конструкции GROUP BY. На практике при попытке выполнить анализ, требуемый для получения агрегированной информации, вскоре обнаруживается, что эта задача является довольно сложной. В отличие от других функций, в которых все действия могут быть реализованы в коде единственного вызова обрабатывающего кода, в агрегирующей функции приходится чередовать действия самой функции (то, что фактически сводится к агрегированию) с действиями, выполняемыми в СУБД SQL Server одновременно с этим (например, с организацией групп для конструкции GROUP BY). В связи с этим приходится применять своего рода поэтапные вызовы класса сборки. По этой причине предусмотрены четыр этапа вызова класса, и в каждом из этих вызовов допускается поддержка различных методов, как описано ниже. Init. На этом этапе обеспечивается инициализация функции. Если речь идет об агрегирующей функции, то с помощью данного метода может быть создан своего рода накопитель или объявлена какая-то другая вспомогательная переменная; иными словами, метод Init позволяет инициализировать переменные, обеспечивающие накопление данных, и другие дополнительные переменные. Accumulate. Этот метод вызывается в СУБД SQL Server по одному разу для каждой строки, обрабатываемой с помощью агрегирующей функции. Разработчику дано полное право использовать функцию в соответствии с собственным замыслом, но предполагается, что метод Accumulate будет служить для реализации той логики накопления данных, которая должна лечь в основу агрегирующей функции. Merge. СУБД SQL Server - это многопотоковое приложение, и в нем вполне допускается использование многочисленных потоков, в каждом из которых может вызываться одна и та же конкретная функция. Как таковой метод Merge может применяться для объединения результатов, полученных с помощью различных потоков, в один окончательный результат. В зависимости от типа создаваемой агрегирующей функции решение задачи объединения данных может оказаться довольно сложным. Тем не менее допускается возможность использования в классе закрытых методов класса, что позволяет контролировать количество работающих потоков и учитывать вклад, внесенный каждым потоком. Следует отметить, что разрабатываемая агрегирующая функция получает в качестве параметра копию класса (при использовании метода Merge можно рассматривать такую организацию вызова функции как аналог рекурсивного вызова), а не накапливаемое значение какого-либо другого типа; это предусмотрено для того, чтобы предусмотреть возможность получения в агрегирующей функции надлежащих результатов, вычисленных другим потоком. Terminate. Метод Terminate противоположен методу Init. Именно вызов этого метода приводит к фактическому получению результата. Теперь рассмотрим применение описанных методов на практике. Для этого необходимо прежде всего создать новый проект в программе Visual Studio (в рассматриваемом примере автор назвал проект Example Aggregate), а затем добавить к нещ новую агрегирующую функцию (щелкните правой кнопкой мыши на проекте в разрабатываемом решении и выберите Add Aggregate). После этого в СУБД SQL Server создается стандартный шаблон, который включает все четыре метода, описанных выше:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |