SQL - статьи

       

SQL Server в вопросах и ответах


#01/99

Карен Уоттерсон независимый журналист, редактор и консультант по клиент-серверным системам и хранилищам данных. Ей можно написать по адресу .
Брайан Моран президент группы пользователей и директор по технологиям СУБД Spectrum Technology Group. Имеет сертификаты MCSE, MCSD и MCT. Ему можно написать по адресу .

В: Я установил SQL Server 7.0, но когда я запускаю Enterprise Manager, я не вижу баз данных master, model и msdb. Кроме того, я не вижу системных таблиц в пользовательских базах данных. В чем причина?

О: Вы указали SQL Server не отображать системные объекты. Щелкните правой клавишей мыши на имени сервера в Enterprise Manager и выберите Edit SQL Server Registration Properties. Поставьте метку в окошке напротив надписи Show system databases and objects.

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

В: Из-за особенности типа datetime в SQL Server 6.5 затруднены арифметические действия над датами и их форматирование. Почему в SQL 7.0 Microsoft не устранила этот недостаток и не добавила функции вроде LAST_DAY (последний день месяца) и NEXT_DAY (следующий день недели)?

О: Мы согласны, что работать с типом datetime трудно. В частности, в SQL Server для выполнения простых арифметических действий над датами (например, для прибавления к заданной дате нескольких дней), приходится пользоваться функцией DATEPART(). Однако при внесении изменений в основные типы данных могут возникнуть серьезные проблемы с обратной совместимостью. В SQL Server 7.0 операции с датами стало осуществлять несколько легче. В качестве примера приведем следующий SQL-код: DECLARE @datevalue datetime SELECT @datevalue = "1/1/99" PRINT "Добавим 5 суток" SELECT @datevalue + 5 PRINT "Теперь добавим 5.25 суток (или 5 суток 6 часов)" SELECT @datevalue + 5.25 Его выполнение на SQL Server 7.0 приводит к следующим результатам: z Добавим 5 суток 1999-01-06 00:00:00.000 Теперь добавим 5,25 суток (или 5 суток 6 часов) 1999-01-06 06:00:00:00.000


Как видно, SQL Server 7.0 позволяет добавлять время к заданной дате (в сутках) с помощью оператора сложения (+). Кроме того, для выполнения той же операции можно воспользоваться командой T-SQL DATEADD, хотя на наш взгляд, с оператором сложения работать проще.

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

В: Для соединения системы на базе SQL Server 6.5 с системой на основе SQL Server 7.0 (я обладаю правами системного администратора) я испробовал следующий метод. На системе с SQL Server 7.0 я выполнил команду sp_addlinkedsrvlogin. Для создания одинакового набора параметров входа на обоих серверах я последовательно присвоил @useself значения FALSE и TRUE. Затем я выполнил sp_addlinkedserver и обновил каталог хранимых процедур на системе с SQL Server 6.5. Однако при попытке выполнить распределенный гетерогенный запрос я получил следующее сообщение об ошибке: Что я сделал неправильно?

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

Провести диагностику данной проблемы без доступа к серверам нелегко, но в подобных случаях причину нередко следует искать в конфигурации NetLib или в конфликтах пользовательских прав на уровне системы безопасности самой NT. Чтобы упростить рассмотрение проблемы, назовем сервер, осуществляющий запрос, , а связанный сервер - . Приведенное сообщение об ошибке говорит о том, что используется соединение Named Pipes, и что SQL Server 7.0 не видит системы с SQL Server 6.5 в сети.

Для успешного выполнения распределенного запроса на обоих серверах должен работать компонент Named Pipes. Кроме того, пользователь, осуществляющий запрос, должен иметь право доступа к сервису NT Server, работающему на физической машине с TargetServer. При инсталляции SQL Server компонент Named Pipes устанавливается по умолчанию, поэтому мы предполагаем, что эта важная часть NetLibs установлена на обе системы, и причина проблемы не в ней.

Если причина не в Named Pipes, то в проблема, возможно, в профиле пользователя, от имени которого осуществляется запрос к TargetServer. Запрос осуществляется от имени пользователя, по регистрации которого на SourceServer был запущен сервис MSSQLServer. Таким образом мы можем сузить круг возможных источников проблемы до двух: либо MSSQLServer работает на SourceServer в пользовательском профиле LocalSystem, который не имеет права доступа к сети; либо MSSQLServer был запущен пользователем, не располагающим правом доступа к сервису NT Server, работающему на TargetServer.

В данном случае сервис MSSQLServer запущен в пользовательском профиле LocalSystem. Чтобы решить проблему, вам необходимо при загрузке войти в систему от имени пользователя, имеющего разрешение на доступ к удаленным машинам.

В: Я воспользовался входящим в состав SQL Server 7.0 мастером создания комплектов сервисов преобразования данных (Data Transformations Services, DTS). Для соединений я сохранил имена, предложенные мне по умолчанию, но я теперь хочу изменить их, придав им более описательный характер. Как это сделать?



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

Допустим, к примеру, вы создали простой комплект, который экспортирует данные из таблицы authors в базе данных pubs в двумерный файл, и вы не снабдили комплект документацией. Для простоты вы сохранили имена соединений, предложенные вам по умолчанию источником OLE DB, на котором они основаны. Другими словами, эти имена практически ничего не говорят об источнике соединения. Когда вы завершили работу над комплектом, ваш начальник потребовал от вас, чтобы названия соединений соответствовали принятым в компании правилам назначения имен.





Экран 1: Создание нового соединения

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

Вначале щелкните правой клавишей мыши на названии соединения и выберите Properties. Затем в показанном на экране 1 диалоге Connection Properties выберите New Connection. Введите в текстовом окне New Connection новое название соединения и нажмите Оk. Система спросит "хотите ли вы, чтобы заданные вами ранее преобразования при создании данного соединения были сброшены?" Нажмите No. Нажмите No еще раз в ответ на следующий вопрос и процесс переименования будет завершен.



О: SQL Server 2000 позволяет хранить дополнительные свойства многих типов объектов базы данных. Дополнительные свойства определяются пользователем и имеют тип SQL_ VARIANT. Программисты, работающие с VB, знакомы с типом данных VARIANT. Подобно типу данных в VB, SQL_VARIANT позволяет хранить различные типы данных в поле, параметре или переменной. Каждый экземпляр столбца SQL_VARIANT состоит из двух частей: собственно данные и метаданные, описывающие значение (например базовый тип данных поля, максимальный размер, точность и collation - сопоставление). Для получения мета-данных экземпляра SQL_VARIANT можно использовать функцию SQL_VARIANT_ PROPERTY.

Например, чтобы сохранить описание столбца au_id в таблице authors в базе данных pubs, нужно щелкнуть правой кнопкой мыши на имени столбца в окне Object Browser (новый интерфейс Query Analyzer), затем выбрать Extended Properties. Теперь следует добавить новое свойство WhatAmI и внести значение "I am the author id column!!!". То же самое можно сделать, используя процедуру sp_addextendedproperty:

sp_addextendedproperty 'WhatAmI2','This is a new property value','user', dbo, 'table', authors, 'column', au_id

Затем можно применить стандартный оператор SELECT с новой функцией fn_listextendedproperty, чтобы извлечь информацию:

SELECT * FROM ::fn_listextendedproperty(NULL, 'user', 'dbo','table','authors', 'column', default)

Objtype objname name value COLUMN au_id WhatAmI I am the author id column!!! COLUMN au_id WhatAmI2 This is a new property value SELECT * FROM ::fn_listextendedproperty(NULL,'user','dbo','table', 'authors', 'column',default)

В: Я имею сертификат MCSE и собираюсь получить сертификат администратора БД (MCDBA). Я знаю, что для развертывания приложений SQL Server недостаточно прочитать специальную литературу. Тем не менее могли бы Вы рекомендовать какие-то источники информации для начинающих? У меня уже есть "Microsoft SQL Server 7.0 System Administration Training Kit" (Microsoft Press, 1999) и William Robert Stanek's "Microsoft SQL Server 7.0 Administrator's Pocket Consultant" (Microsoft Press, 1999).



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

Чтобы приобрести дополнительный опыт, импортируйте необработанные статистические данные в новую базу данных MS SQL или OLAP куб и представьте, что Вы - конечный пользователь, который хочет проанализировать данные. Изучите OLAP и приложение Food Mart. Можно поэкспериментировать с приложением "Duwamish" - его Вы найдете в Microsoft Developer Network (MSDN). Установите и исследуйте его в целом и покомпонентно, пересоберите. Более полную информацию и примеры Вы найдете на сайте Microsoft: и .

Помимо этого, стоит присоединиться к группе новостей news://msnews.microsoft.com/microsoft.public.msdn.duwamish, а также посмотреть новые примеры приложений - Fitch и Mather Stocks на сайте

В: Я писал хранимую процедуру и столкнулся с проблемой при использовании оператора TOP с локальной переменной вместо фиксированного числа. Например, когда я пишу:

DECLARE @Counter INT SELECT @Counter=5 SELECT TOP @Counter * FROM <mytable>

процедура возвращает ошибку. Но строка

SELECT TOP 5 * FROM <mytable>

работает. Что делать в таком случае?

О: Согласно SQL Server Books Online (BOL), можно использовать N в разделе TOP, чтобы ограничить количество строк, возвращаемых в результате исполнения SELECT запроса. Но N должно быть числом типа integer. В SQL Server 7.0 язык Transact SQL (T-SQL) не позволяет задействовать локальную переменную в разделе TOP N, даже если та имеет тип integer. Локальные и глобальные переменные можно идентифицировать с помощью префиксов: @ - для локальных и @@ - для глобальных переменных. Можно также использовать оператор SET, чтобы присвоить значение локальной переменной, или же определить локальные переменные, ссылаясь на них в списке полей оператора SELECT. Следующий пример, вероятно, поможет решить Вашу задачу:

DECLARE @counter INT DECLARE @sql VARCHAR(255) SET @Counter=5 SELECT @sql = <SELECT TOP < + str(@counter) + < * FROM authors> EXEC (@sql)



Это T-SQL-предложение динамически строит и выполняет строку T-SQL, возвращающую первые N строк запроса. Динамический T- SQL позволяет создавать такие команды T-SQL, которые невозможно применять при использовании стандартных T-SQL методов.

В: Как использовать функции, определяемые пользователем (UDF) с SQL Server 2000?

О: Использование UDF в хранимых процедурах позволяет переместить дополнительную бизнес-логику приложения на сервер. При разработке SQL Server 2000 специалисты Microsoft собирались включать поддержку для независимых от языка UDF (например, UDF, записанное в VBScript). К сожалению, в силу существующих программных ограничений, UDFs пока можно создавать лишь на языке SQL (T-SQL). Приведу пример из SQL Server 2000 Books Online (BOL), показывающий, как используется типичная UDF, написанная на T-SQL:

CREATE FUNCTION CubicVolume -- Входные размеры в сантиметрах. (@CubeLength decimal(4,1), @CubeWidth decimal(4,1), @CubeHeight decimal(4,1) ) RETURNS decimal(12,3) - Cubic centimeters. AS BEGIN RETURN ( @CubeLength * @CubeWidth * @CubeHeight ) END

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

Карен Уоттерсон

независимый журналист, редактор и консультант по клиент-серверным системам и хранилищам данных. Ей можно написать по адресу: .

Брайан Моран

президент группы пользователей и директор по технологиям СУБД Spectrum Technology Group. Имеет сертификаты MCSE, MCSD и MCT. Ему можно написать по адресу: .


Содержание раздела