Отправляет email-рассылки с помощью сервиса Sendsay

MS SQL Server

  Все выпуски  

MS SQL Server - дело тонкое...


Информационный Канал Subscribe.Ru


#165<<  #166

СОДЕРЖАНИЕ

1.СОВЕТЫ
1.1.XML за 20 минут!
2.ССЫЛКИ НА СТАТЬИ
2.1.Статьи на русском языке
2.2.Новые и обновлённые технические статьи Microsoft
2.3.Англоязычные статьи
3.ФОРУМ SQL.RU
3.1.Самые популярные темы недели
3.2.Вопросы остались без ответа

СОВЕТЫ

XML за 20 минут!

По материалам статьи Leon Platt: XML IN 20 MINUTES!
Перевод Максима Зубова

С помощью этой статьи, вы быстро погрузитесь в XML. Я буду брать предметы из повседневной жизни, и пытаться описывать их, используя XML. Затем я загружу файл XML в объектную модель документов XML. После этого я продемонстрирую, как запрашивать XML документы с помощью XPath и проделывать некоторые основные манипуляции над ними. Все эти действия будут продемонстрированы с использованием простого приложения на Visual Basic и Microsoft Parser версии 3.0. Заключительной целью этой статьи будет разработка элемента управления ActiveX , который будет запрашивать данные из базы данных pubs на SQL Server и возвращать список наименований книг в формате XML.

1. Введение

Если кто-либо из вас когда-нибудь пытался изучить XML своими силами, Вы возможно встречались со многими сбивающими с толку понятиями, обрушившимися и на меня в свое время. DTD, XML Schema, пространства имен (namespaces), XPath, XPointers, XSL, XSLT, DOM, SAX, SOAP, Все, я сдаюсь. Добавлю лишь, что большинство из этих материалов основано на реализациях, код которых может содержать ошибки. Наверняка существуют миллионы способов реализации и использования XML, но они все могут быть достаточно сложны. А знаете, XML может быть и очень простым. Если мы забудем про DTD, XML Schemas, пространства имен (namespaces), и т.п.
Стараясь быстрее обучить вас работе с XML, я буду по возможности игнорировать приличную долю информации, которую вы и так сможете прочитать в соответствующей литературе. И первое что я собираюсь проигнорировать, это пространства имен (namespaces) и схемы (schemas). Вам это может показаться странным, так как большинство книг начинаются именно с объяснения этих понятий, но постарайтесь думать об XML как о средстве решить конкретную задачу, как, например, о молотке. Для того чтобы пользоваться молотком, разве обязательно знать, как построить дом? Что если все что мне нужно, это просто вбить гвоздь чтобы повесить на него картину? То же самое и с XML, он может быть и очень сложным, достаточно универсальным для использования в сотнях, если не в тысячах приложений, и очень простым, если не обращать внимания на некоторые вещи. В этой статье, я буду концентрироваться на решении конкретных проблем с помощью XML.
Так в чем же собственно проблема? Давайте предположим, что я хочу описать простой объект, например стакан, используя XML. Зачем я собираюсь использовать XML для этого? Ну, во-первых, это как раз то, для чего и предназначен XML. XML описывает данные. В моем примере, стакан, это и есть данные. В жизни, данными могут быть документы Word, листы электронных таблиц, изображения, книга, запись базы данных, или даже классы C++ или Visual Basic. Во вторых, XML расширяем. XML позволяет мне создавать столько признаков, сколько необходимо для описания данных и эти признаки будут такими, какими я захочу. И, наконец, потому что XML быстро становится стандартом. Если на Марсе есть жизнь, то можете не сомневаться, что они там смогут понять мой XML файл.

Какие основные свойства позволяют описать стакан?


Материал, из которого он сделан
    Прозрачный ли материал или нет
Высота в дюймах
Количество унций, которое в него помещается
Его содержимое
 Описание любых твердых тел и их количества
 Описание любых жидкостей и их объема
 Описание любой другой субстанции и ее количество
Имеет или не имеет он крышку

Как бы то же самое выглядело в формате XML?


<?xml version="1.0"?>
<CUP>
<MATERIAL transparent="yes">glass</MATERIAL>
<HEIGHT units="inches">6</HEIGHT>
<VOLUME units="ounces">16</VOLUME>
<CONTENTS>
 <SOLID qty="2">ice cube</SOLID>
 <SOLID qty="1">straw</SOLID>
 <LIQUID qty="3" units="ounces">water</LIQUID>
 <OTHER qty="0"/>
</CONTENTS>
<LID>yes</LID>
</CUP>

Заметьте, что первая строка файла () имеет специальный вид, пока, просто запомните, что она должна быть тут. Прелесть формата XML в том, что любой может понять, о чем в нем говориться, просто внимательней взглянув на него. Понятно также, что это не единственное из возможных XML описаний стакана. Если я попрошу 10 человек разработать XML описание стакана с одинаковыми свойствами, возможно, все они создадут разные, но верные описания. Вот тут как раз и кроется проблема. Возможно не для нас, людей, но когда компьютер читает XML файл, то было бы отличной идеей, дать ему знать, о чем этот файл. Вот тут и всплывает пространство имен (namespaces) и схемы (schemes). Проще говоря, схемы используются для определения адекватной структуры для XML файла.
Теперь настало время поговорить о нескольких простых правилах XML, которым необходимо придерживаться:

Правило XML #1: Адекватный XML файл должен в точности соответствовать своей схеме. Но для простоты понимания материала, ни один из моих примеров не будет использовать схемы. Таким образом, строго говоря, ни один из моих примеров не "адекватный". Но, честно говоря, мне все равно. Я не собираюсь строить дом, мне нужно всего лишь повесить картину. Я подробней расскажу об этом позже, когда будем обсуждать объектную модель документов XML.

Правило XML #2: Если вы программируете на VB, запомните: XML чувствителен к регистру. XML чувствителен к регистру. XML чувствителен к регистру. XML чувствителен к регистру. Напишите это предложение 1000 раз и никогда не забудете.

Правило XML #3: Тэги принято называть элементами и каждый открывающийся тэг, должен иметь соответствующий ему закрывающийся тэг. Следуя этому правилу, у вас получится правильный XML файл. Это очень важно, потому что до тех пор, пока XML файл не будет правильно оформлен, он не будет проанализирован и не загрузится в объектную модель документов. Заметьте, если элемент не содержит значений и не содержит других (вложенных) элементов, закрывающий тэг может иметь вид <Element /> вместо более громоздкой конструкции <Element></Element>. Можете увидеть такой подход в предыдущем примере (<OTHER qty="0"/>).

Правило XML #4: Элементы могут содержать атрибуты, а значения атрибутов должны быть заключены в кавычки (одинарные или двойные).

Правило XML #5: Можно несколько раз использовать имена атрибутов, но имена элементов должны быть уникальны для всего файла. В предыдущем примере, атрибут qty имел различное значение в зависимости от того, в каком элементе он используется <SOLID>,<LIQUID>, или <OTHER>. Значение атрибута зависит от контекста его использования. Тогда как значение элемента всегда означает одно и то же, независимо от того, в каком месте файла атрибут находится. В предыдущем примере, элемент <SOLID> и <HEIGHT> всегда имеет одно и то же значение во всем нашем документе. <HEIGHT> например, всегда используется для описания высоты стакана.

Правило XML #6: В XML есть несколько специальных символов, которые не могут быть использованы напрямую, потому что являются зарезервированными в синтаксисе XML. Поэтому, для использования таких символов, придется использовать зарезервированную конструкцию, начинающуюся с символа & и специального кода, (символ & должен писаться как &amp;) (символ " должен писаться как &quot;) (символ < должен писаться как &lt;) (символ > должен писаться как &gt;) и (символ ' должен писаться как &apos;). Вместо этого, также можно использовать инструкцию <![[CDATA[...]]>, где на месте "...." может быть любая последовательность символов, кроме "]]>". Такая конструкция может встречаться в любом месте, но она не может быть вложенной.

2. Объектная модель документов XML

Объектная модель документов XML позволяет программистам загружать содержимое XML файла в память. Как только XML файл загружен таким образом, с ним можно работать, используя свойства, методы и события объектной модели документов. Вот где как раз и проявляется польза XML. Объектная модель документов значительно облегчает выборку и обработку информации XML файла. Я не буду тут рассказывать обо всех возможностях объектной модели документов, расскажу лишь о некоторых основных возможностях, которые помогут в достижении цели этой статьи. Я возьму только что созданный XML файл с описанием стакана, загружу его в объектную модель документов и проделаю несколько действий с ним. Остальные особенности и возможности объектной модели документов я приберегу для следующей статьи, рассказывающей о клиентском XML. Заметьте, не смотря на то, что объектная модель документов очень хороша и удобна для разработчиков, она требует довольно значительного объема системных ресурсов. Поэтому существует еще один метод анализа XML файлов, известный как SAX. Моя статья не претендует на исчерпывающий источник информации по этому вопросу, поэтому было бы полезно также воспользоваться XML SDK.

2.1. Загрузка XML файла

Давайте посмотрим на пример, используя анализатор Microsoft's XML версии 3.0 (Microsoft's XML parser version 3.0 (msxml3.dll)) чтобы разобраться, как же это все работает. Если у вас нет анализатора, то последнюю версию можно скачать с сайта Microsoft.
Предположим, я сохранил пример описания стакана в формате XML в файл "http://web_server/xml/cup.xml" (локальный путь C:\inetpub\wwwroot\xml\cup.xml) и теперь хочу загрузить его в объектную модель документов. Следующий код предполагает, что анализатор уже загружен и работает.


Код на Visual Basic 6.0:  
   (устанавливаем связь с Microsoft XML, v3.0)
Dim xmlDoc as MSXML2.DOMDocument30
Set xmlDoc = New DOMDocument30
xmlDoc.async = False
xmlDoc.validateOnParse = False
xmlDoc.load ("c:\inetpub\wwwroot\xml\cup.xml")
msgBox xmlDoc.xml

ASP Server-Side код на Visual Basic:
Dim xmlDoc
Set xmlDoc = Server.CreateObject("Msxml2.DOMDocument.3.0")
xmlDoc.async = False
xmlDoc.validateOnParse = False
xmlDoc.load  "/xml/cup.xml"

ASP Server-Side код на Java Script:
var xmlDoc = Server.CreateObject("Msxml2.DOMDocument.3.0");
xmlDoc.async = false;
xmlDoc.validateOnParse = false;
xmlDoc.load ("/xml/cup.xml");

Пояснение приведённого кода - пройдемся по коду на VB6

Строка 1: Dim xmlDoc as MSXML2.DOMDocument30

В этой первой строке определяем ссылку на "Microsoft XML, v3.0". В этой строке я определил переменную xmlDoc как ссылку на XML документ. MSXML2 это библиотека (используйте это название, не пытайтесь написать MSXML3, это не будет работать). DOMDocument30 определяет объект XML документа соответствующий версии 3.0. Вы также можете встретить такой код: dim xmlDoc as MSXML2.DOMDocument. Такой конструкцией обычно пользуются, когда не хотят указывать конкретную версию XML документа. В этом случае будет использоваться зарегистрированный по умолчанию в системе анализатор. Проблема может быть только в том, что версия анализатора, зарегистрированная по умолчанию, может отличаться на разных компьютерах. Если вы хотите быть уверенными в том, что написанный вами код будет работать с любой версией анализатора, то не используйте в нем специфических для конкретных версий анализатора конструкций. Потому, что нет никакой гарантии, что у пользователя, который будет пользоваться вашим кодом, установлена имена та версия анализатора, под которую вы писали свой код. Еще одно преимущество разработки кода, независимого от версии анализатора в том, что когда выходит более новая версия анализатора, у нее обязательно будет обратная совместимость с предыдущими версиями, и вам не придется перекомпилировать ваш код.

Строка 2: Set xmlDoc = new DOMDocument30

В этой строке происходит инициализация переменной xmlDoc как нового экземпляра объекта XML документа версии 3.0.

Строка 3: xmlDoc.async = False

Файлы XML могут быть загружены либо в синхронном, либо в асинхронном режиме. Если xmlDoc.async = False, то значит, что содержимое XML фала будет загружено, и только после этого управление будет передано вызывающему процессу. Если xmlDoc.async = True, то значит, что управление будет передано вызывающему процессу сразу, не дожидаясь, пока содержимое XML файла будет полностью загружено.

Строка 4: xmlDoc.validateOnParse = False

Этот код сообщает о том, что анализатор не должен проверять загружаемый XML файл на соответствие своей схеме (validateOnParse = False). Для того, чтобы включить проверку на соответствие схемы, нужно написать validateOnParse = True.

Строка 5: xmlDoc.load ("C:\inetpub\wwwroot\xml\cup.xml")

В этой строке вызывается метод загрузки указанного XML файла. Существует два вида метода загрузки. Первый, который написан в строке 5, загружает файл в объектную модель документов, и при этом нужно обязательно передавать полный путь до XML файла. Второй вариант загрузки предусматривает передачу в качестве параметра xml строку. Такой вид загрузки мог бы быть вызван, например, так: xmlDoc.loadXML("корректная xml строка"). Я покажу, как пользоваться этим способом позже.

Строка 6: MsgBox xmlDoc.xml

Эта строка отображает содержимое загруженного XML файла. В результате мы должны получить тот исходный XML файл, который создали ранее.

2.2. Исследование объектной модели документов XML

Создайте в Visual Basic новый проект и назовите его standard.exe. Вставьте приведенный выше код в метод загрузки главного окна вашего проекта. Убедитесь, что вы объявили ссылку именно на "Microsoft XML v3.0". Для того, чтобы это сделать, нажмите Project-->References, затем пролистайте появившийся список вниз и найдите в нем нужную ссылку. Заметьте, анализатор версии 3.0 должен быть установлен на вашем компьютере, иначе в списке его не будет. Установите точки остановки на последней строке кода (msgbox xmlDoc.xml). Запустите приложение в режиме отладки. Когда процесс выполнения дойдет до точки остановки, вызовите окно "Locals" и посмотрите объектную модель документов. Можно многое узнать, просматривая то, что отображено в этом окне. Окно "Locals" должно быть похоже на то, что изображено на рисунке ниже. Вот некоторые интересные свойства объектной модели документов.

Объектная модель документов XML всегда содержит два узла верхнего уровня:

  • Item1 это корень ветви элементов документа (не обращайте на нее внимания)
  • Item2 на самом деле первый элемент документа (запомните это)

nodeName или baseName - могут быть использованы при поиске имени элемента или атрибута.
nodeType - используйте для того, чтобы получить тип текущего узла.
nodeValue - используете для того, чтобы узнать значение данных узла.
childNodes - это коллекция узлов-потомков. Они могут быть узлами элементов, текстовыми узлами и узлами CDATA. Могут быть и другие типы узлов, про которые я сейчас рассказывать не стану, но вы сможете узнать все про них в XML SDK.
attributes - это коллекция узлов атрибутов текущего элемента.
length - используется для определения количества узлов в дереве непосредственно принадлежащих текущему.
xml - это свойство присутствует во всех узлах и может быть использовано для представления текущей позиции в документе. XML строка начинается с текущего узла и проходит вниз до конца дерева. Это очень полезное свойство. Поэкспериментируете с ним и увидите, что получится.

2.2.1. Успешная загрузка

2.2.2. Узлы элементов

Узел элементов может содержать узлы потомки элементов, атрибутов, текста или CDATA. Из рисунка ниже видна следующая информация об узле "SOLID":

nodeType - Тип текущего узла = NODE_ELEMENT - т.е. текущий узел является элементом.
nodeName или baseName или tagName - Название текущего узла (элемента) = SOLID.
Его родительский элемент CONTENTS имеет 4 потомков.
Это можно увидеть на следующем рисунке, но SOLID имеет одного потомка, который имеет текстовый тип данных.
text - "ice cube" это сокращенный метод, позволяющий получить значение текущего узла без перемещения к текстовому узлу потомка.

2.2.3. Узлы атрибутов

Узлы атрибутов могут состоять только из текстовых или CDATA узлов-потомков. На следующем рисунке показано, какая информация может быть получена об узле "qty":

nodeType - Тип текущего узла = NODE_ATTRIBUTE - текущий узел является атрибутом.
nodeName или baseName - Имя текущего узла (Атрибутов) = qty

Из следующего рисунка также понятно, что qty имеет одного потомка, который имеет текстовый тип данных.
text или value - "2" это сокращенный метод, позволяющий получить значение текущего узла без перемещения к текстовому узлу потомка.

2.2.4. Текстовые узлы и узлы CDATA

Текстовые или CDATA узлы не содержат потомков. Текстовые узлы содержат обработанные текстовые данные своего родительского узла. CDATA содержат необработанные текстовые данные своего родительского узла. CDATA узлы создаются, когда данные в XML файле специальным образом обрамлены. Метка CDATA говорит анализатору не разбирать данные и принимать символы внутри этой метки как данные. Секция CDATA особенно полезна, когда нужно вставить код внутрь XML файла. На следующем рисунке показано, какая информация может быть получена из текущего текстового узла:

nodeType - Тип текущего узла = NODE_TEXT - текущий узел содержит текстовые данные.
nodeName - Имя текущего узла (текстового) = #text - все текстовые узлы называются #text
data или text или value - "2" - это текущие данные узла.

2.2.5. Ошибки при загрузке документа

Секция parseError объектной модели документов может оказаться полезно при выявлении проблем, возникающих при загрузке XML документа. Если я удалю закрывающий тег от OTHER в файле нашего примера и попытаюсь запустить программу еще раз, то получу следующий результат. Первая часть полезной информации, это то, что наш nextSibling теперь содержит значение Nothing. Теперь, если вы посмотрите на childNodes, вы можете увидеть, что поле length теперь равно 0. Оба этих признака говорят о том, что наш XML документ не был загружен. Чтобы разобраться почему, я открываю узел parseError и получаю всю информацию об ошибках.

2.3. Запросы к XML документу

Итак, я показал вам, как загрузить XML файл в объектную модель документов, но что с ним там делать? Одна из основных возможностей, которой вы сможете пользоваться это выполнять различные запросы к XML документу. Для этого вы конечно можете просматривать весь документ до тех пор, пока не найдете информацию которую ищите. Но наиболее предпочтительный способ, это использование одного из двух методов класса DOMDocument. Два метода используемые для поиска узлов в нашем предыдущем примере могли бы выглядеть как xmlDoc.SelectSingleNode(patternString) - для получения искомого узла, или xmlDoc.SelectNodes(patternString) - для получения списка искомых узлов. Параметр patternString как раз и является запросом. Он может быть сформирован одним из двух способов. Либо как XSL запрос, либо как XPath запрос. Более новый и предпочтительный способ создавать запросы к XML документу, это XPath. Формат patternString должен быть установлен заранее, перед первым вызовом любого из двух методов запроса данных, иначе по умолчанию будет использоваться XSL способ формирования запросов. Для установки типа формирования patternString используйте setProperty("SelectionLanguage", "format"). Для того, чтобы изменить запросы в нашем примере таким образом, чтобы использовался способ XPath, я добавлю следующую команду: setProperty("SelectionLanguage","XPath"). По-моему, XPath это самая важная технология в XML которую следует изучить. Я приведу несколько простых XPath запросов. Хорошим началом для изучения этой технологии может служить Microsoft XML SDK. Еще одним способом для объяснения этого, могло бы быть написание простого приложения на Visual Basic, которое позволяет вводить запросы и выводить результат. Вы, возможно, найдете какие-нибудь бесплатные приложения, которые делают то же самое, но XPath довольно новый и может не вполне поддерживаться этими приложениями.

2.3.1. Использование XPATH для выполнения запросов к объектной модели документов

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


Dim objNode As IXMLDOMNode
Dim objListOfNodes As IXMLDOMNodeList
xmlDoc.setProperty "SelectionLanguage", "XPath"
MsgBox "Your cup contains the following items"
Set objListOfNodes = xmlDoc.selectNodes("//CONTENTS/*")
For Each objNode In objListOfNodes
    MsgBox objNode.Text
Next

Запустите программу и посмотрите, что получится. Вы должны получить четыре сообщения, в которых говориться о содержимом стакана. Последнее сообщение должно быть пустым, потому, что элемент "OTHER" не содержит никакого текста. Давайте составим запрос, который возвращает все содержимое стакана, где qty>0. следующая строка кода делает именно это:


Set objListOfNodes = xmlDoc.selectNodes("//CONTENTS/*[@qty>0]")

ОТЛИЧНО! Давайте теперь добавим еще один запрос, который позволит нам определить, есть ли у стакана крышка или нет. Добавьте следующий код в конец предыдущего:


Set objNode = xmlDoc.selectSingleNode("/CUP/LID")
if objNode.text="yes" then
    MsgBox "We have a lid"
else
    MsgBox "No lid on this cup"
end if

Пройдемся по коду строка за строкой:

Строка 1: Dim objNode As IXMLDOMNode

В этой строке определяется переменная objNode типа узел XML документа. Важно понимать, что узел XML документа это тоже объект. Это не значение. Он состоит сам из себя, также как и его атрибуты и потомку (childNodes). Этим способом вы можете отсекать ненужные ветви дерева, выбирая только нужные.

Строка 2: Dim objListOfNodes As IXMLDOMNodeList

В этой строке определяется переменная objListOfNodes имеющая тип списка узлов XML документа (группы узлов).

Строка 3: xmlDoc.setProperty "SelectionLanguage", "XPath"

Эта строка устанавливает способ формирования patternString как XPath.

Строка 4: MsgBox "Your cup contains the following items:"

Строка 5: Set objListOfNodes = xmlDoc.selectNodes("//CONTENTS/*[@qty>0]")

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

  • //CONTENTS - взять все элементы CONTENTS в XML документе. Заметьте: // - это краткое обозначение для всего содержимого XML документа.
  • /* - из списка элементов CONTENTS взять все (* - используется для указания всех) элементы-потомки. Это сокращает полученный результат до четырех узлов элементов (<SOLID><SOLID><LIQUID><OTHER>). Эти четыре узла попадают напрямую под узел CONTENTS.
  • [@qty>0] - проверить каждый элемент-потомок на то, чтобы его атрибут qty (@ - означает атрибут) был больше 0. Если это условие не выполняется, узел отбрасывается. Все, что внутри [ ] в XPath запросе может принимать значения True или False. Если результат True, то узел сохраняется. Если результат False, то узел отбрасывается. После этого наш результат сокращается до трех узлов (<SOLID><SOLID><LIQUID>).

Строка 6-8: For Each objNode In objListOfNodes / MsgBox objNode.Text / Next

Эти строки отображают значения каждого узла элемента, которые соответствуют запросу. ("ice cube" , "straw" , "water").

Строка 9: Set objNode = xmlDoc.selectSingleNode("/CUP/LID")

Эта строка возвращает все элементы LID, которые принадлежат элементу CUP, который, в свою очередь, порожден от корня дерева (когда запрос начинается с /, то это означает что начинать нужно с корня). Это очень похоже на путь к файлу или папке. В нашем примере, этот запрос вернет элемент LID, который содержит значение "yes". Важно тут то, что я указал запросу начинать с корневого элемента XML документа. Запросы не всегда начинают выполняться с корневых элементов, обычно они начинаются с текущего узла. В нашем примере это не имеет значения, поскольку текущим узлом (xmlDoc) и является корневой элемент XML документа (но не во всех случаях это так).

Строка 10-15: if objNode.text="yes" then / MsgBox "We have a lid" /
else / MsgBox "No lid on this cup" /end if

Эта строка отображает сообщение "We have a lid" потому, что текстовое свойство элемента LID "yes".

3. Преобразование ADO в XML

Теперь, когда вы поняли основы XML, давайте создадим элемент управления ActiveX, который будет конвертировать набор данных ADO в XML формат. Цель в том, чтобы получить наименования книг из таблицы Titles базы данных Pubs и вернуть их в формате XML. Результат, который получится я буду использовать в своей следующей статье. Вы можете сказать, ADO имеет свои собственные методы для сохранения результата в формате XML, правильно? Да, но если доверить это ADO, то в итоге я получу XML файл в таком ужасном формате, что с ним невозможно будет работать. ADO создаст XML файл с использованием пространства имен, а мне сейчас это совсем не нужно. Во-вторых, ADO создаст XML файл, который будет представлен в форме атрибутов. Иными словами, каждая запись станет элементом и каждое поле - атрибутом:


<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
 xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
 xmlns:rs='urn:schemas-microsoft-com:rowset'
 xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
 <s:ElementType name='row' content='eltOnly'>
  <s:AttributeType name='title_id' rs:number='1' rs:writeunknown='true'>
   <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='6' 
   rs:maybenull='false'/>
  </s:AttributeType>
  <s:AttributeType name='title' rs:number='2' rs:writeunknown='true'>
   <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='80' 
   rs:maybenull='false'/>
  </s:AttributeType>
  <s:AttributeType name='type' rs:number='3' rs:writeunknown='true'>
   <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='12' 
   rs:fixedlength='true' rs:maybenull='false'/>
  </s:AttributeType>
  <s:AttributeType name='price' rs:number='4' rs:nullable='true' 
  rs:writeunknown='true'>
   <s:datatype dt:type='number' rs:dbtype='currency' dt:maxLength='8' 
   rs:precision='19' rs:fixedlength='true'/>
  </s:AttributeType>
  <s:AttributeType name='ytd_sales' rs:number='5' rs:nullable='true' 
  rs:writeunknown='true'>
   <s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' 
   rs:fixedlength='true'/>
  </s:AttributeType>
  <s:AttributeType name='notes' rs:number='6' rs:nullable='true' 
  rs:writeunknown='true'>
   <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='200'/>
  </s:AttributeType>
  <s:AttributeType name='pubdate' rs:number='7' rs:writeunknown='true'>
   <s:datatype dt:type='dateTime' rs:dbtype='timestamp' dt:maxLength='16' 
   rs:scale='3' rs:precision='23' rs:fixedlength='true'
    rs:maybenull='false'/>
  </s:AttributeType>
  <s:extends type='rs:rowbase'/>
 </s:ElementType>
</s:Schema>
<rs:data>
 <z:row title_id='BU1032' title='The Busy Executive's 
      Database Guide' type='business ' price='19.99'
   ytd_sales='4095' notes='An overview of available database systems with 
   emphasis on common business applications. Illustrated.'
   pubdate='1991-06-12T00:00:00'/>
 <z:row title_id='BU1111' title='Cooking with Computers: Surreptitious 
      Balance Sheets' type='business ' price='11.95'
   ytd_sales='3876' notes='Helpful hints on how to use your 
   electronic resources to the best advantage.' 
   pubdate='1991-06-09T00:00:00'/>
</rs:data>
</xml>

А мне бы хотелось получить XML файл в форме элементов, где каждая запись, содержалась бы в теге <BOOK>, и каждое поле было бы элементом внутри тега <BOOK>. Синтаксис моей XML строки был бы таким:


<TITLES>
<BOOK>data from table
    <FIELD prettyname="Book identification number" tablename="titles" 
 columnname="title_id" datatype="number" filter="">data from table</FIELD>
    <FIELD prettyname="Title of the book" tablename="titles" 
 columnname="title" datatype="text" filter="">data from table</FIELD>
    <FIELD prettyname="Type of book" tablename="titles" columnname="type" 
 datatype="text" filter="">data from table</FIELD>
    <FIELD prettyname="Price of the book" tablename="titles" 
 columnname="price" datatype="number" filter="">data from table</FIELD>
    <FIELD prettyname="Year todate sales" tablename="titles" columnname="ytd_sales" 
 datatype= "number" filter= "">datafrom table</FIELD>
    <FIELD  prettyname="Datepublished" tablename= "titles" columnname="pubdate" 
 datatype="date" filter= "">datafromtable</FIELD>
 </BOOK>
</TITLES>

Кстати, то, что я только что сделал, это создал схему для моей XML строки. Теперь, если мне нужно сверить структуру XML документа со схемой, все что мне останется сделать, это преобразовать схему в правильный формат. То есть в синтаксис DTD или XDR. Заметьте, что я добавил некоторые атрибуты к каждому элементу <FIELD>. Одна из причин этого в том, что эта информация может быть использована клиентом. Prettyname могут быть использованы как метки данных. Атрибут datatype мог бы быть использован для проверки данных на стороне клиента. Но чтобы быть честным, истина причина того, что появились эти атрибуты в том, что они имеют особое назначение в шаблоне XSL фала, который я часто использую для построения секции where SQL запросов. Может быть, я скоро опубликую статью, демонстрирующую этот подход. Шаблон на самом деле очень полезный. Когда XML структура применяется к данным из таблицы Titles, результат будет выглядеть следующим образом:


<TITLES>
     <BOOK>The Busy Executive's Database Guide
          <FIELD prettyname="Title Identification Number" tablename="titles" 
    gcolumnname="title_id" datatype="number" gfilter="">BU1032</FIELD>
   <FIELD prettyname="Title of the Book" tablename="titles" 
   gcolumnname="title" datatype="text" gfilter="">
   The Busy Executive's Database Guide</FIELD>
   <FIELD prettyname="Type of Book" tablename="titles" gcolumnname="type" 
   datatype="text" gfilter="">business    </FIELD>
   <FIELD prettyname="Price of the Book" tablename="titles" 
   gcolumnname="price" datatype="number" gfilter="">19.99</FIELD>
   <FIELD prettyname="Year to date sales" tablename="titles" 
   gcolumnname="ytd_sales" datatype="number" gfilter="">4095</FIELD>
   <FIELD prettyname="Notes about the book" tablename="titles" 
   gcolumnname="notes" datatype="memo" gfilter="">
   An overview of available database systems with emphasis on common business 
   applications. Illustrated.</FIELD>
   <FIELD prettyname="Date Published" tablename="titles" 
   gcolumnname="pubdate" datatype="date" gfilter="">6/12/1991</FIELD>
     </BOOK>
     <BOOK>Cooking with Computers: Surreptitious Balance Sheets
          <FIELD prettyname="Title Identification Number" tablename="titles" 
    gcolumnname="title_id" datatype="number" gfilter="">BU1111</FIELD>
   <FIELD prettyname="Title of the Book" tablename="titles" 
   gcolumnname="title" datatype="text" gfilter="">Cooking with Computers: 
   Surreptitious Balance Sheets</FIELD>
   <FIELD prettyname="Type of Book" tablename="titles" gcolumnname="type" 
   datatype="text" gfilter="">business    </FIELD>
   <FIELD prettyname="Price of the Book" tablename="titles" 
   gcolumnname="price" datatype="number" gfilter="">11.95</FIELD>
   <FIELD prettyname="Year to date sales" tablename="titles" 
   gcolumnname="ytd_sales" datatype="number" gfilter="">3876</FIELD>
   <FIELD prettyname="Notes about the book" tablename="titles" 
   gcolumnname="notes" datatype="memo" gfilter="">Helpful hints on 
   how to use your electronic resources to the best advantage.</FIELD>
   <FIELD prettyname="Date Published" tablename="titles" 
   gcolumnname="pubdate" datatype="date" gfilter="">6/9/1991</FIELD>
     </BOOK>
</TITLES>

Теперь я получил что-то, с чем можно работать!

Листинг 1 - CUP.XML


<?xml version="1.0"?>
<CUP>
<MATERIAL transparent="yes">glass</MATERIAL>
<HEIGHT units="inches">6</HEIGHT>
<VOLUME units="ounces">16</VOLUME>
<CONTENTS>
 <SOLID qty="2">ice cube</SOLID>
 <SOLID qty="1">straw</SOLID>
 <LIQUID qty="3" units="ounces">water</LIQUID>
 <OTHER qty="0"/>
</CONTENTS>
<LID>yes</LID>
</CUP>

Листинг 2 - Загрузка Cup.xml в объектную модель документов


Dim xmlDoc As MSXML2.DOMDocument30
Set xmlDoc = New DOMDocument30
xmlDoc.async = False
xmlDoc.validateOnParse = False
xmlDoc.Load ("c:\inetpub\wwwroot\xml\cup.xml")
MsgBox xmlDoc.xml
Dim objNode As IXMLDOMNode
Dim objListOfNodes As IXMLDOMNodeList
xmlDoc.setProperty "SelectionLanguage", "XPath"
MsgBox "Your cup contains the following items"
Set objListOfNodes = xmlDoc.selectNodes("//CONTENTS/*[@qty>0]")
For Each objNode In objListOfNodes
    MsgBox objNode.Text
Next
Set objNode = xmlDoc.selectSingleNode("/CUP/LID")
If objNode.Text = "yes" Then
    MsgBox "We have a lid"
Else
    MsgBox "No lid on this cup"
End If

Листинг 3 - Элемент управления ActiveX: ADO в XML (WebClass.dll)(xmlControl.cls)


Option Explicit

'Declare Database variables
Private m_dbConnection As New ADODB.Connection
Private m_dbCommand As ADODB.Command
Private m_adoRs As ADODB.Recordset
Private m_adoErrors As ADODB.Errors
Private m_adoErr As Error
Public nCommandTimeOut As Variant
Public nConnectionTimeOut As Variant
Public strConnect As Variant
Public strAppName As String
Public strLogPath As String
Public strDatabase As String
Public strUser As String
Public strPassword As String
Public strServer As String
Public strVersion As String
Public lMSADO As Boolean
'Private Global Variables
Private gnErrNum As Variant
Private gstrErrDesc As Variant
Private gstrErrSrc As Variant
Private gstrDB As String
Private gstrADOError As String
Private Const adLeonNoRecordset As Integer = 129
Private gtableName(6) As String
Private gcolumnName(6) As String
Private gprettyName(6) As String
Private gdatatype(6) As String
Private gfilter(6) As String

Private Function OpenDatabase()

If Len(strConnect) = 0 Then  'устанавливаем значения по умолчанию
    If Len(strDatabase) = 0 Then
        strDatabase = "pubs"
    End If
    
    If nConnectionTimeOut = 0 Then
        nConnectionTimeOut = 600
    End If
    
    If nCommandTimeOut = 0 Then
        nCommandTimeOut = 600
    End If
    
    If Len(strAppName) = 0 Then
        strAppName = "xmlControl"
    End If
    
    If Len(strUser) = 0 Then
        strUser = "sa"
    End If
    
    If Len(strPassword) = 0 Then
        strPassword = ""
    End If
    
        strConnect = "Provider=SQLOLEDB.1; " & _
           "Application Name=" & strAppName & _
           "; Data Source=" & strServer & "; Initial Catalog=" & strDatabase & "; " & _
           " User ID=" & strUser & "; Password=" & strPassword & ";"
End If

 'подключаемся к SQL Server и открываем базу данных
On Error GoTo SQLErr  'Включаем обработчик ошибок
With m_dbConnection
    .ConnectionTimeout = nConnectionTimeOut
    .CommandTimeout = nCommandTimeOut
    .Open strConnect  'открываем базу данных, используя строку подключения
End With
On Error GoTo 0  'выключаем обработчик ошибок

OpenDatabase = True  'база данных открыта успешно

Exit Function

SQLErr:
Call logerror("OPEN")
OpenDatabase = False

End Function

Private Function BuildSQLwhere(tmpWhere) As String

 'Это на будущее

End Function

Public Function GetTitlesXML(Optional xmlWhere As Variant) As String

Dim whereClause As String
Dim strSQL As String

Call OpenDatabase  'открываем базу данных pubs

If IsMissing(xmlWhere) Then  'когда запрос не прошел
    whereClause = ""
Else
    whereClause = BuildSQLwhere(xmlWhere)'конвертируем запрос в правильный sql
End If

 'инициализируем sql выражение которое будет запрашивать заголовки книг
strSQL = "select title_id,title,type,price,ytd_sales,notes,pubdate from titles " & whereClause

Call NewRecordSet  'создаем набор данных
  'устанавливаем cursorlocation
    m_adoRs.CursorLocation = adUseClient
     'открываем набор записей
    m_adoRs.Open strSQL, m_dbConnection, adOpenForwardOnly, adLockReadOnly, adCmdText

 'отключаемся от набора данных
Set m_adoRs.ActiveConnection = Nothing

On Error GoTo 0  'выключаем обработчик ошибок
    
 'закрываем базу данных и освобождаем подключение
Call CloseDatabase

If m_adoRs.EOF Then
    GetTitlesXML = ""  'запрос не вернул ни одного значения
Else
    If lMSADO Then
        GetTitlesXML =  msado(m_adoRs)  'конвертируем набор данных в Microsoftado-->xml
    Else
        GetTitlesXML = ADOtoXML(m_adoRs, True)  'convert the ado recordset to custom xml
    End If
End If

 'закрываем набор данных
Call CloseRecordset
    
Exit Function

SQLErr:
    Call logerror(strSQL)

End Function

Private Function ADOtoXML(tmprs As ADODB.Recordset, tmpMP As Boolean) As String

Dim adoFields As ADODB.Fields 'объявляем коллекцию для хранения полей
Dim adoField As ADODB.Field  'используется для получения каждого поля из коллекции
Dim xmlDoc As msxml2.DOMDocument30
Dim tmpLine As String  'хранит xml представление каждой книги
Dim tmpXML As String  'служит для конкатенации xml строк
Dim i As Integer

If tmprs.EOF Then  'запрос не вернул ни одну запись
    ADOtoXML = ""
    Exit Function
Else
    Set adoFields = tmprs.Fields  'создаем коллекцию полей
End If

tmpXML = "<TITLES>"  'все книги будет заключены в тег <TITLES>

Do Until tmprs.EOF  'цикл по каждой строке в наборе данных
    i = 0  ' I - индекс ado поля, который начинается с 0 - первое поле будет field(0)
    tmpLine = "<BOOK>" & tmprs("title") & vbCrLf
    For Each adoField In adoFields   'цикл по всем полям
         'строим xml тег <FIELD> и его атрибуты для текущего поля
        tmpLine = tmpLine & "<FIELD " 
        tmpLine = tmpLine & "prettyname=""" & gprettyName(i) & """ "
        tmpLine = tmpLine & "tablename=""" & gtableName(i) & """ 
  gcolumnname=""" & adoField.Name & """ "
        tmpLine = tmpLine & "datatype=""" & gdatatype(i) & """ gfilter="""""
        tmpLine = tmpLine & ">" & adoField.Value
        tmpLine = tmpLine & "</FIELD>" & vbCrLf
        i = i + 1  'переходим на следующее поле
    Next
    tmpXML = tmpXML & tmpLine & "</BOOK>" & vbCrLf  'закрывающий тег после последнего поля
    tmprs.MoveNext  'следующий заголовок
Loop
Set adoField = Nothing  'уничтожаем объект-поле
Set adoFields = Nothing  'уничтожаем объект-коллекцию полей

tmpXML= tmpXML & "<?xml version="1.0"?></TITLES>" & vbCrLf  'закрывающий тег </TITLES>
Set xmlDoc = New msxml2.DOMDocument30  'создание xmlDOM 
xmlDoc.async = False  'ждем когда документ загрузится
xmlDoc.validateOnParse = False  'не сверяемся со схемой
xmlDoc.loadXML(tmpXML)  'загружаем строку в объектную модель документов
On Error Resume Next  'если файл не существует, то обрабатываем эту ошибку
Kill("c:\temp\custom.xml")   'стираем файл если он существует 
On Error GoTo 0  'говорим обработчику ошибок прерываться при обнаружении ошибки 
xmlDoc.save ("c:\temp\custom.xml")  'сохраняем xml в файл
ADOtoXML=xmlDoc.xml  'возвращает xml строку
Set xmlDoc=Nothing  'уничтожаем объектную модель документов

End Function 

Private Function msado(tmprs As ADODB.Recordset) As String 

Dim xmlDoc As msxml2.DOMDocument30
On Error Resume Next  'если файла не существует, получаем ошибку
Kill ("c:\temp\msado.xml")  'стираем файл, если он существует
On Error  GoTo 0  ' говорим обработчику ошибок прерываться при обнаружении ошибки
tmprs.save "c:\temp\msado.xml", adPersistXML  ' сохраняем xml в файл
Set xmlDoc = New msxml2.DOMDocument30  'создаем объектную модель документов xml
xmlDoc.async = False  'ждем загрузки xml документа
xmlDoc.validateOnParse = False  'не сверяемся со схемой
xmlDoc.Load ("C:\temp\msado.xml") 'загружаем файл в объектную модель документов
msado =   xmlDoc.xml  'возвращаем xml строку
Set xmlDoc = Nothing   'уничтожаем объектную модель документов

End Function 

Private SubCloseRecordset()      
     
 'закрываем набор данных 
m_adoRs.Close 
Set m_adoRs =Nothing  

End Sub 

Private Sub NewRecordSet() 

Set m_adoRs= Nothing 
Set m_adoRs=New ADODB.Recordset

End Sub 

Private Sub CloseDatabase()               

m_dbConnection.Close
Set m_dbConnection =Nothing 

End Sub 

Private Sub logerror(errSQL As String)        
       
Dim hFile As Integer
Dim expFile As String
 
On Error GoTo 0
gnErrNum = Err.Number 
gstrErrDesc =Err.Description 
gstrErrSrc = Err.Source Set
m_adoErrors = m_dbConnection.Errors 

For Each m_adoErr In m_adoErrors
 gstrADOError =   m_adoErr.Description & "," & CStr(m_adoErr.NativeError)
 _ & "," & CStr(m_adoErr.Number) & "," &
 m_adoErr.Source  _ & "," & CStr(m_adoErr.SQLState)
Next 

hFile =FreeFile
If Len(strLogPath) = 0 Then 
    strLogPath = "C:\temp\" 
End If 
expFile = strLogPath & strAppName & ".err" 
Open expFile For Append As  #hFile
    
Print #hFile,"**********************************" 
Print #hFile, Now() 
Print#hFile, "**********************************" 
Print #hFile,"Subroutine: " & tmpPro
Print #hFile, "Error Number:"  & gnErrNum  
Print#hFile,  "Error Description: "  & gstrErrDesc 
Print #hFile, "Error Source:"  & gstrErrSrc 
Print #hFile, "Ado error String: " & gstrADOError 
Print #hFile, "Bad SQL: " & errSQL 
Close #hFile
End Sub 

 Private Sub Class_Initialize() 
strVersion = "xmlControl Version 1.1"     
 'title_id,title,type,price,ytd_sales,notes,pubdate
gtableName(0) = "titles"
gcolumnName(0) = "title_id"
gprettyName(0) = "Title Identification Number"
gdatatype(0) = "number"
gfilter(0) = ""
gtableName(1) = "titles"
gcolumnName(1) = "title"
gprettyName(1) = "Title of the Book"
gdatatype(1) = "text"
gfilter(1) = ""
gtableName(2) = "titles"
gcolumnName(2) = "type"
gprettyName(2) = "Type of Book"
gdatatype(2) = "text"
gfilter(2) = ""
gtableName(3) = "titles"
gcolumnName(3) = "price"
gprettyName(3) = "Price of the Book"
gdatatype(3) = "number"
gfilter(3) = ""
gtableName(4) = "titles"
gcolumnName(4) = "ytd_sales"
gprettyName(4) = "Year to date sales"
gdatatype(4) = "number"
gfilter(4) = ""
gtableName(5) = "titles"
gcolumnName(5) = "notes"
gprettyName(5) = "Notes about the book"
gdatatype(5) = "memo"
gfilter(5) = ""
gtableName(6) = "titles"
gcolumnName(6) = "pubdate"
gprettyName(6) = "Date Published"
gdatatype(6) = "date"
gfilter(6) = ""

End Sub

Листинг 4 - Тестовое приложение на VB для проверки WebClass


Private Sub Command1_Click()

Dim objWC As xmlControl
Dim xml As String
Set objWC = New xmlControl
objWC.strDatabase = "pubs"
objWC.strServer = "ltweb"
objWC.strUser = "sa"
objWC.strPassword = ""
objWC.lMSADO = Option2.Value
objWC.strAppName = "Article1"
Text1.Text = objWC.getTitlesXML

End Sub

Листинг 5 - ASP для тестирования WebClass


<%@ Language=VBScript %>
<%
 'Используем WebClass элемента управления ActiveX чтобы вернуть xml в браузер
 '
 'до того, как со страницей можно будет работать, WebClass.dll должен быть зарегистрирован 
 'на вэб-сервере.
 'Анализатор microsoft xml версии 3.0 (msxml3.dll) тоже должен быть зарегистрирован
 '
set objWC = Server.CreateObject("WebClass.xmlControl")
objWC.strDatabase =  "pubs"
objWC.strServer = "ltweb"  'замените ltweb именем вашего SQL сервера
objWC.strUser ="sa"  'замените sa именем пользователя вашего SQL сервера
objWC.strPassword=""  'сюда введите пароль для этого пользователя
objWC.strAppName="Article1"
objWC.lMSADO=false  'true вернет microsoft ado-->xml
 'false вернет пользовательский xml
 '
Response.ContentType="text/xml"  'устанавливаем тип содержимого для браузера
Response.write objWC.getTitlesXML  'получаем the xml отображаем его
 '
set objWC=nothing  'уничтожаем объект
%>

[В начало]

ССЫЛКИ НА СТАТЬИ

Статьи на русском языке

Использование метаданных SQL Server
Bill Graziano
MSSQLServer: Представления информационных схем являются частью стандарта SQL-92. Этот стандарт определяет ряд представлений, которые призваны предоставлять информацию о базе данных. Например, есть представление по имени TABLES, которое предоставляет информацию о таблицах базы данных. Вы можете сделать запрос к этому представлению, точно так же как и к любому другому представлению...
Разработка расширенных хранимых процедур для MS SQL Server 2000. Часть 2
Release
MSSQLServer: Вот мы и подошли к реализации нашего технического задания, о котором я говорил Вам в первой части статьи. Теперь мы знаем достаточно, чтобы справиться с этой задачей...
Сценарии и примеры практического применения OLAP-инструментов
Intersoft Lab
OLAP: О преимуществах применения технологии OLAP сказано и написано немало. Однако для многих по-прежнему остается открытым вопрос — как использовать инструменты этого класса в информационной инфраструктуре предприятия? Поэтому в этой статье мы решили представить различные сценарии и примеры практического использования OLAP-средств при построении корпоративных систем анализа и подготовки управленческой отчетности. Приведенные примеры отражают реальный опыт компании Intersoft Lab, накопленный при внедрении OLAP-продуктов Аналитической Платформы Контур...
Доступ к журналу событий из командной строки
Марк Минаси
MSSQLServer: На каждом компьютере Windows Server 2003, Windows XP, Windows 2000 и Windows NT есть по меньшей мере три журнала. Эти журналы — бесценный источник информации; однако получить к ним доступ очень трудно. Если на предприятии имеется 1000 рабочих станций и серверов, то администратору предстоит регулярно исследовать не менее 3000 журналов. Но с помощью инструмента командной строки операционных систем Windows 2003 и XP можно собирать и фильтровать информацию из журналов событий с локальных и удаленных машин, даже с компьютеров, на которых установлены старые версии операционных систем, предшествующие XP...
Передача журналов в SQL Server 2000, Часть 2
Рон Телмейж
MSSQLServer: Когда рабочий сервер базы данных отключается, например, на время планового технического обслуживания или в результате поломки, нужно быть уверенным в том, что база данных останется в целости и сохранности на резервном сервере. Эту уверенность может дать только хорошо продуманный способ синхронизации первичного и резервного серверов. В SQL Server 2000 Enterprise Edition и в SQL Server 2000 Developer Edition передача журналов осуществляется с помощью встроенной утилиты Enterprise Manager. Microsoft SQL Server 2000 Resource Kit поставляется с пакетом неподдерживаемых хранимых процедур для других редакций SQL Server 2000 (см. врезку "Простой способ передачи журналов в SQL SERVER 2000 STANDART EDITION"), а Microsoft BackOffice Resource Kit предлагает неподдерживаемый метод п...
Работа с журналом событий SQL Server
Ильдар Даутов
MSSQLServer: В процессе функционирования SQL Server ведет журнал, в котором регистрирует события, связанные с работой сервера. В документации этот журнал называется Error Log, что не вполне соответствует действительности. Правильнее было бы именовать его Event Log, так как в нем отмечается множество событий различного характера из разных источников, включая системные информационные и системные аварийные события, сообщения аудита регистрации и пользовательские сообщения (если сравнивать с операционной системой, то в Windows NT/2000 события регистрируются в трех журналах — Application, Security и System)....
Параметрическое определение порядка сортировки данных
Ицик Бен-Ган
MSSQLServer: В различных сетевых форумах часто обсуждается вопрос: как получить отсортированные результаты выполнения запроса, передавая хранимой процедуре некоторый параметр? Я собрал несколько решений этой задачи, предложенных талантливыми программистами. Основная часть идей, изложенных в этой статье, принадлежит обладателям звания SQL Server MVP Брюсу П. Марголину и Нейлу Пайку, а одно замечательно остроумное решение предложил Ричард Ромли. Некоторые из представленных в этой статье решений наряду с множеством решений других задач, связанных с SQL Server, можно найти в книге Нейла Пайка "SQL Server: Common Problems, Tested Solutions", вышедшей в издательстве Apress в 2000 году...
Полезные советы при работе с T-SQL
Кимберли Трипп
MSSQLServer: Мне часто приходится слышать, что обратиться к производственной базе данных не составляет никакого труда, особенно из Enterprise Manager. Для обеспечения необходимого уровня безопасности и высокой готовности системы администратору базы данных нужно изменить процедуры ее обслуживания и внесения изменений. Предлагаю вниманию читателей несколько советов, которые могут пригодиться DBA уже сейчас...
DTS на ходу
Шейн Доверс
MSSQLServer: После пяти лет программирования в Data Transformation Services (DTS), прошедших со времени выпуска SQL Server 7.0, я пришел к выводу, что одной из наиболее важных целей при создании пакетов DTS является оптимизация переносимости на уровне проекта. Оптимальная переносимость означает виртуальную способность пакета исполняться на любом сервере. Если в процессе разработки пакета, вы все время помните о переносимости, то когда вы будете переносить пакет с одного сервера на другой, вам придется внести в него незначительные изменения или не нужно будет вносить изменений совсем. Переносимость важна потому, что большинство разработчиков создают пакеты на специально предназначенных для этого серверах, а затем перемещают окончательную, протестированную версию на производственный с...
Все о том, что такое ничего
Рас Уитни
MSSQLServer: Чтобы использовать сервер OLAP для разработки аналитического приложения, необходимо выучить язык запросов сервера, в случае Analysis Services - MDX. А для того чтобы писать аккуратные запросы, вы должны понимать, как этот язык обрабатывает значение null (пустые ячейки данных). Разные серверы OLAP обращаются с пустыми ячейками по-разному. Даже если два сервера OLAP (например, Analysis Services и Essbase от Hyperion) могут поддерживать MDX в качестве языка запросов, они не обязательно обрабатывают пустоты одинаковым образом...
Анализ содержимого программы Money
Рас Уитни
MSSQLServer: Большинство аналитических приложений, с которыми я работаю, содержат данные, принадлежащие другим людям, и конфиденциальными подробностями, которые могут скрываться в этих данных, я не интересуюсь. Наверное, многие администраторы баз данных и разработчики находятся в такой же ситуации. Но анализируя данные, которые имеют какой-то смысл лично для вас, вы получаете более глубокое понимание OLAP. Свой первый осмысленный опыт работы с OLAP я получил, когда мой друг прислал мне куб с результатами футбольных матчей колледжа за 13 лет. Куб содержал статистику побед и поражений всех команд в различных игровых ситуациях. После двух часов сосредоточенного составления сводных таблиц, анализа мелких деталей, вычерчивания диаграмм и создания специализированных критериев я обнаружил ...
Перспективы распределенных вычислений
Брайан Моран
MSSQLServer: Каким сегодня представляется будущее распределенных вычислений (grid computing)? Пока Microsoft не делает никаких намеков относительно распределенных вычислений в SQL Server. А компания Oracle не переставая твердит о функциях организации распределенных вычислений в своем новом продукте, Oracle 10g, который должен быть выпущен в 2004 г. Потенциальный выигрыш в производительности и удобство использования распределенных вычислений игнорировать невозможно...
Еще немного о связях
Джеффри Бэйн
MSSQLServer: Если бы работа администратора или разработчика баз данных ограничивалась только программированием в среде SQL и обеспечением качественного резервного копирования, у нас бы, наверное, оставалось больше свободного времени. Но, увы, в число важных задач, помимо прочего, входит эффективная поддержка баз данных...
Удаление совпадающих записей
Ответы от разработчиков SQL Server
MSSQLServer: Для удаления из таблицы множественных строк можно объединить таблицу и представление, применяя операцию DELETE. Сценарий в Листинге показывает, как применить представление v1 в качестве фильтра для удаления строк из таблицы t1. Сначала сценарий создает две таблицы и представление, вставляет некоторые данные, а затем удаляет строки из первой таблицы, которая имеет идентификатор (ID), совпадающий с ключом представления...
Доступ к именованному экземпляру через UDP Port 1434 закрыт
Брайан Моран
MSSQLServer: Некоторое время назад в одной из статей я отвечал на следующий вопрос читателя: "Я разработал псевдоним сервера, который использует сетевую библиотеку TCP/IP. Псевдоним сервера со стороны клиента сконфигурирован к динамически устанавливающемуся порту. Как можно узнать, какой порт используется клиентом, чтобы полностью заблокировать наш брандмауэр?"...

[В начало]

Новые и обновлённые технические статьи Microsoft

FILE: OLAP_DSO.exe: OLAP DSO Type Library, Header and Interface DLL for Use in C++
HOW TO: Enable SSL Encryption for SQL Server 2000 with Microsoft Management Console
HOW TO: Program the SQL Merge Control by Using Visual C# .NET
HOW TO: Program the SQL Snapshot and SQL Distribution Control with Visual C# .NET
HOWTO: Use CDao for Connections to a Secure Attached Table
INF: Additional Fallback Considerations
INF: Analyzing and Avoiding Deadlocks in SQL Server
INF: Changes to SQL Server 6.5 That Affect 6.0 Apps
INF: Deferred Constraints and Disable_Def_Cnst_Chk
INF: Desktop Version Is Configured for Local Access Only
INF: How Grant and Revoke work in SQL Server 6.5.
INF: How to Change the Sleep Value Used by Dbdataready
INF: How to Create an Extended Stored Procedure to Do a Pager Notification
INF: How to Troubleshoot SQL Server Merge Replication Problems
INF: How to Upgrade SQL Server 6.5 and 7.0 to SQL Server 2000 (White Paper)
INF: Microsoft Corp. SQL Server Analysis Services (White Paper)
INF: No Results From SQLDescribeParam or SQLProcedureColumns
INF: NoRemapPipes Error Message Occurs in System Log when You Use SQL Server 2000 on a Windows 2000 Cluster
INF: ODBC Catalog Functions in Static Cursors
INF: Powerful and Accessible Analysis for Business (White Paper)
INF: Protocol Error in TDS Stream Causes Function Sequence Error from OLE Automation SPs
INF: Registering SQL 6.0 Servers from a 6.5 SEM Workstation
INF: Requirements To Implement Cell-Level Security with OLAP Services
INF: Resolving Deadlocks With Distributed Transactions
INF: Running SQL Server 6.5 INSTCAT.SQL on SQL Server 6.0.
INF: SET SHOWLPLAN_ALL and the Microsoft SQL Server ODBC Driver for SQL Server 2000
INF: SQL Server ODBC Driver Performance Analysis Tools
INF: SQL Server Replication with eEnterprise and Dynamics Product
INF: SQLXML Managed Classes (White Paper)
INF: Tips for Debugging Stored Procedures from VC++
INF: Troubleshooting SQL Executive and Task Scheduling
INF: T-SQL Debugger Is Turned Off By Default for Earlier Clients After You Install SQL Server 2000 Service Pack 3
INF: UPDATETEXT Must Be Run in the Published Database
INF: Use of DBCC GAMINIT
INF: Use the "-SkipErrors" Parameter in Distribution Agent Cautiously
INF: Using SQL Server 6.5 DMO Against a SQL Server 6.0 Server
INF:Foreign Key Constraint Behavior of Nullable Composite Keys
Live Communications Server Unexpectedly Quits After You Remove SQL Server 2000
SQL Server 2000 User-Defined Functions White Paper

[В начало]

Англоязычные статьи

In the Picture
Itzik Ben-Gan
An abstract look at drawing with T-SQL. Editor's Note: Send your experts-only T-SQL tips to Itzik Ben-Gan at blackbelt@sqlmag.com. If we use your tip in the magazine, you'll receive $100 and an exclusive T-SQL Black Belt shirt
Using XML Bulk Load to Load ADO-Generated XML Data
Rich Rollman
Editor's Note: Send your XML questions to Rich Rollman at xmlquestions@sqlmag.com. I have an XML document generated from a Recordset through the ADO Save method. I want to use XML Bulk Load to upload the data in the XML document into another database, but the upload fails when the XML contains date fields. How can I use XML Bulk Load to load ADO-generated date fields?
Q&A: Basic security practices can ward off Slammer-like worms
Maryann Tripp
When the Slammer worm hit last month, it choked large Internet service providers worldwide. Slammer exploited a vulnerability in Microsoft SQL Server and spread without the assistance of an e-mail attachment, the vehicle of choice for most worms. Instead, it used the SQL monitor port to spread to other vulnerable systems. Nearly a month later, the worm and the havoc it caused are a distance memory for some. However, according to security expert Ed Yakabovicz, the impact of a security breach such as the one posed by Slammer can be prevented, or at least limited, by following a few basic, but important, security practices
Export a Table to a Date Stamped File Name in SQL Server
MAK Muthusamy Anantha Kumar
Date stamping is a very common requirement in the IT industry for any data extract created. Through the DTS package with ActiveX script, it is very easy to date stamp a file. In this article, I am going to walk you through how to export a table to a date stamped file
Microsoft rolls out public beta for SQL Server reports
James Niccolai
SQL Server 2000 Reporting Services is due out by the end of the year. OCTOBER 10, 2003 ( IDG NEWS SERVICE ) - Microsoft Corp. today released the first public beta of a product that should allow developers to build and manage reports using its SQL Server 2000 database. It also disclosed pricing for the product and pegged it for release by the end of the year
Anti-Blocker Strategies
Sancho Fock
No reasonable strategy for the resolution of concrete blocking problems can be found until one has determined the precise nature of the scale block. The most obvious criterion for distinguishing between different scale blocks is their average duration. The following categories emerge as a result of this division
Tuning Indexes
Vakhtang Baya Pavliachvilli
Having appropriate indexes can make a world of difference in an application’s performance. As applications change and features are added or dropped, so do the queries going against the database. Therefore you should examine your current set of queries often to decide how to best alter your indexing scheme
Terminal Services - A Couple Tips
Andy Warren
The only thing neater than Terminal Services (TS) is sliced peanut butter. Hopefully most of you know that TS (aka Remote Desktop) gives you an easy way to do remote administration. If you've got TS enabled on your server and you can get a connection, you can log on as if you were there. Saves many trips to the server room. If you haven't tried it, it's definitely worth exploring
The comparison of SQL Server 2000 with MySQL v4.1
Alexander Chigrik
Often people in newsgroups ask for a comparison of Microsoft SQL Server and MySQL. In this article, I compare SQL Server 2000 with MySQL version 4.1 regarding price, performance, platforms supported, SQL dialects and product limitations
Picture This: BLOBs
Trudy Pelzer
Binary Large OBject (BLOB) is nothing new. Any old-timer can recall dBASE’s infamous “memo” fields (circa 1988), the introduction of Oracle’s LONG and LONG RAW data types (c. 1987), the first use of VARGRAPHIC fields in IBM DB2 (c. 1984), and Microsoft’s first use of Sybase SQL Server, which included TEXT and IMAGE data types (c. 1988). But BLOBs, in the 2003 model, are new and improved since the days of yore
Implementing CRUD Operations Using Stored Procedures: Part 1
Andrew Novick
CRUD: A coating or an incrustation of filth or refuse. That's the American Heritage dictionary definition but not the database definition. When you are working with databases, CRUD is an acronym for the four essential database operations: Create, Read, Update, and Delete
SQL Server Reporting Services Aims to Bring Simplicity to Building, Managing, Distributing Reports
REDMOND, Wash., Oct. 10, 2003 -- While reporting is a critical part of a company, it has historically not been an easy task. Reporting mechanisms are rarely a part of the database package, which means organizations must purchase them from a third party. These frequently did not integrate with applications common throughout the rest of the organization, making development and sharing of reports challenging and laborious
Getting to the Root of Slammer
Brian Moran
Wow! It's been a while since my commentaries generated such a wide range of heated opinions. Two weeks ago, I slammed DBAs (pun intended) for failing to apply the hotfix that would have shut down the SQL Slammer worm ("After the Slammer,"). Last week, I apologized to DBAs for oversimplifying the Slammer situation and laying all the blame on their shoulders ("SQL Server DBAs Deserve an Apology," ). I also asked you, the readers, to share what you thought Microsoft could and should do to help us maintain secure systems. This week, let's look at a sampling of feedback about my Slammer columns and your suggestions about how Microsoft can help us avoid Slammer-like problems in the future
A Comparison of SQL Server 2000 with DB2 v8.1
Alexander Chigrik
Often people in newsgroups ask about a comparison of DB2 and Microsoft SQL Server. In this article I will compare SQL Server 2000 with DB2 Universal Database version 8.1 regarding price, performance, platforms supported, SQL dialects, and products limits
When Do You Pull Your Hair Out?
Steve Jones
Another "In the Real World" adventure. I'm sure that after reading about a few of my "In The Real World" adventures, there are more than a couple of you that are starting to doubt my abilities. I know, I know, I probably would too since it seems like I've had more than my share of disasters
Have a Little Respect for SQL Databases
Jack D. Herrington
As we race towards better object technology, some people seem content to put relational database systems out to pasture—for no good reason
Resolving Deadlocks in SQL Server 2000
Ron Talmage
Your application can detect a deadlock and resubmit its transaction, but a better approach is to resolve a deadlock by changing the conditions that lead to it in the first place
Smash SQL Speed Barriers
Dan Fox
Gain direct access to SQL Server data with SqlClient. ADO.NET's slick, direct data access to SQL Server provides a speedy alternative to ODBC and even OLE DB. ODBC and OLE DB work well when you can't go straight to the source, but you can achieve better performance with SQL Server and Visual Studio .NET by taking advantage of the SqlClient .NET Data Provider. The end result: You'll speed up both application development and the resulting SQL apps
Backing Up and Restoring SQL Server Databases and Transaction Logs
Alexander Chigrik
The backing up and restoring of databases and transaction logs is a way that SQL Server provides to protect from data loss. The backup operation creates a copy of a database. This copy can be used to restore the database if media failure occurs or if the database is somehow damaged (for example, from user errors)
Troubleshooting SQL Server 2000 installation
Alexander Chigrik
Should you have problems installing SQL Server 2000, review this troubleshooting checklist to find potential solutions
Useful scripts to clear out old plan history logs
Paul Mandella
This tip was originally submitted to our sister site SearchWin2000.com's tip exchange. When a plan's history gets long, it helps to be able to clear out any old ones that you don't need to see anymore. Use the following scripts rather than deleting them one at a time via Enterprise Manager. These will give you a count of each and the ability to delete based on date
Problem-solving blocking situations
Robert Hauck
This procedure is intended to help with problem-solving blocking situations on the server. I developed it to contact users when their client software holds locks that are holding up other users. This works faster than viewing the blocking status through Enterprise Manager. It has been tested on SQL Server 2000
Create More Efficient Database Code
Dino Esposito
Take a look under the hood of the SQL Server .NET Data Provider and discover how it can help you improve your ADO.NET code. Using the native data providers in .NET results in more efficient code than using OLE DB. The native providers improve raw performance and enable comfortable data structures to hold data. I'll show you how the .NET data providers are architecturally superior to OLE DB providers by taking the particular case of SQL Server 2000. I'll demonstrate what goes on when you call the classes of both providers, and how SQL Server gets into the game in both cases. I'll show you how this all works by using the SQL Profiler to snoop under the hood of the ADO.NET-to-SQL Server interaction
Transcript of Eric Rudder's February 2003 keynote presentation at VSLive! San Francisco
Well, good morning. Everybody awake? Everybody using Visual Studio .NET? By show of hands, just I like to know who I'm talking to and especially since I come from a VBITS tradition, I'm kind of curious on language, how many of you use VisualBasic.NET as your primary language in Visual Studio? That's a good chunk. How many use Visual C# as their primary language? That's pretty good. How many use C++? Smaller. J#? COBOL? Fortran? OK. This language independence thing, we can go on for 27 questions
Get Ready for Yukon
Roger Jennings
The next release of SQL Server promises increased developer productivity and reduced DBA workload
Microsoft Hopes New Features Will Warm Up End-Users to Yukon
Joe McKendrick
10/1/03 — The wait for Yukon – the code name for the next release of SQL Server – is on, but, unfortunately, it’s going to take longer than first thought. The new database is now scheduled to ship in the second half of 2004, timed to coincide with the release of next version of Microsoft's Visual Studio toolkit
News about Yukon (SQL Server .NET / SQL Server 2004 / SQL Server 2005)
Seit fast zwei Jahren spannt Microsoft uns mit dem neuen SQL Server auf die Folter, der unter dem Namen "Yukon" entwickelt wird. Einzelne Informationen sind dabei immer wieder durchgesickert, insbesondere die Integration der CLR in den SQL Server, sodass Stored Procedures in Managed Code geschrieben werden konnen. Auf der TechEd 2003 in Barcelona hat Euan Garden mehr Details zur Programmierung des neuen SQL Servers verraten. Hier eine Stichwortartige Zusammenfassung des Vortrags "DBA234"
Mapping Database File Objects and Fragmentation
Chris Kempster
Within the Oracle Enterprise Manager suite of utilities, one that has been around for some years is the tablespace manager that allows the DBA to graphically see object distribution within the tablespace. After much searching, I have found no equivalent utility on the SQL Server market, and some would argue that there is no real need. Either way, this article provides the catalyst for such a product and presents a text based solution you can explore this with
SQL 2000 Replication Architecture
Mahesh Kodli
Database management systems are among the most important software systems driving the information age. In many Internet applications, a large number of users who are geographically dispersed may routinely query and update the same database. In this environment, the location of the data can have a significant impact on application response time and availability. A centralized approach manages only one copy of the database

[В начало]

ФОРУМ SQL.RU

Самые популярные темы недели

Как у вас организована система прав на доступ к данным?
Tool Вы знаете что твориться на ваших 10-30+ серверах ?
Поможите оптимизировать...
Массовые блокировки в tempdb
Вопрос по хорошему стилю проектирования БД
Защита SQL - кода от несанкционированного доступа
Как сделать, чтобы триггер запустился всего ОДИН раз за всю операцию
Не в меру умный ADODB.Recordset и как с ним бороться.
Четыре SCSI-диска. Как распорядиться ?
Копирование строк
Вопрос по репликации (не пойму кое-чего)
Оптимизация производительности
Backup по сети
Передача XML-запроса с помощью диалекта MSSQLXML
Microsoft.Jet.OLEDB.4.0 для dBase 5.0. и кодировка
Транзакция существенно увеличивает скорость обработки?
Зависимость производительности от размера Кэша
Нужен совет по организации ежеминутных обсчетов
Большая загрузка при бэкапе лога
AS/400 и MS SQL Server 7.0

[В начало]

Вопросы остались без ответа

Установка MS SQL 7.0 под Windows 2000 Serv/WS
Про курсоры
Небольшой оффтоп по софту.
Доступ к данным в проекте на MSDE
Не вижу данные в DimentionEditor
MSSQL 7.0 and hardware compression on HP DLT vs80
замена Enterprise Manager
IB как LinkedServer
Sql-бяка
?? коннект через Linked Server в MServer2000 к PostGree (FreeBSD)
Обновление параметров step-а job-а
Связывание файлов с объектами БД
Как узнать стартован ли Full-Text Search сервис

[В начало]


Вопросы, предложения, коментарии, замечания, критику и т.п. присылайте Александру Гладченко на адрес: mssqlhelp@pisem.net

sql.ru Описание рассылки

МИНИФОРМА
ПОДПИСКИ




http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное