Dimdim SoftWare
Мастерская Dr.dimdim
ГлавнаяПоискНаписать письмо
ГлавнаяМоделированиеПроектированиеТЗРазработкаИнтерфейсСтатьиСсылкиАвтор
Главная > ЧаВО

FAQ Разработка на MS SQL Server

Подготовлено на основе
материалов НПО "Компьютер", г. Ижевск,
опубликованных на сайте http://www.comp.udmnet.ru/


Q: Написал команду типа "delete … from … where …", но удалил не те данные, которые хотелось бы. Можно ли вернуть?

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

Способ 1. Самый лучший. Внимательно проверять запрос, перед тем как его выполнить!

Способ 2. Преобразуйте delete в select с теми же from и where и проверьте, что он возвращает. Например, требуется выполнить такую команду:

delete from Table1
from Table2 t2
where t2.Fld1=Table1.Fld2

Проверим, что будет удалено таким запросом:

select Table1.*
from Table1, Table2 t2
where t2.Fld1=Table1.Fld2

Способ 3. Это способ требует большой внимательности. Суть способа - использование механизма транзакций для отката возможных некорректных действий. Для этого:

  • перед удалением начинать явно транзакцию командой "begin transation";
  • после удаления в этом же коннекте посмотреть, что реально удалилось и, если все сработало правильно, завершить транзакцию командой "commit transation";
  • o если же что-то пошло не так, то можно откатить транзакцию командой "rollback transaction".

Q: Есть ли ограничения на количество таблиц в запросе?

A: Есть. В MS SQL 6.5 - 16 таблиц. Причем в это количество входят таблицы в подзапросах и во VIEW. Пока известен только один способ борьбы с ограничением - создавать рабочие таблицы и выносить часть запроса в них. Причем при использовании большого количества (6 и более) таблиц в MS SQL 6.5 резко замедляется выполнение запроса и резко увеличивается загрузка процессора. Иногда может помочь, если перед выполнением запроса послать команду "set forceplan off". Эта команда заставляет сервер не умничать, а выполнять запрос так как ему сказали, не оптимизируя его. После выполнения запроса необходимо послать команду "set forceplan on".

В MS SQL 7.0 ограничение на количество таблиц значительно слабее (кажется, там можно использовать 256 таблиц). Причем не наблюдается замедления при увеличении количества таблиц.


Q: Если в where написано t.LAcc=s.CHET, и оба эти поля равны null, то условие ложно. Почему?

A: Дело в том, что SQL Server очень трогательно относится к значениям null. Если поле может принимать значение null, то лучше всего в условия использовать функцию isnull(). Например, так - isnull(t.LAcc,0)=isnull(s.CHET,0).


Q: Выделили переменную размером 255 символов, присвоили ей строку из 4 символов, а затем пытаемся дописать к этой строке какую-нибудь переменную. Результат нулевой. Почему?

A: MS SQL Server (по крайней мере 6.5) умничает по поводу выделения памяти. Если строке присвоено 4 символа, то он и выделит 4, а не 255 как просили. Решением может служить первоначальное присвоение не константы, а переменной, чтобы он не смог догадаться о ее длине.


Q: Возможен ли рекурсивный вызов триггеров?

A: Прямой рекурсии триггера на одно и то же событие не происходит. Косвенная рекурсия возможна. Т.е. - если в триггере на update сделать update этой же таблицы, то триггер второй раз не вызовется, но если update будет сделан в ХП, которая вызвана в триггере, то вызовется уже другой экземпляр триггера на update. Также триггеры на разные события вызываются друг из друга. Только для всего этого необходимо, чтобы параметр сервера 'nested triggers' имел значение 1. Проверить это можно, вызвав команду "sp_configure 'nested triggers'" и проверив колонку "run_value".


Q: SQL-сервер не принимает дату в таком виде - '13.12.97'. Что делать?

A: По умолчанию дата в SQL-запросе принимается в следующем формате - mdy. Изменить это можно с помощью команд SET DATEFORMAT. Синтаксис: set dateformat mdy|dmy|ymd. Действует на текущий коннект.


Q: Сколько столбцов может быть в таблице?

A: В MS SQL Server - 6.5 - 250
В MS SQL Server - 7.0 - 1024


Q: Заношу в строковое поле значение "" (пустые кавычки). При последующем селекте вижу в поле один пробел. Почему?

A: Microsoft говорит, что при попытке послать в строковое поле типа varchar() значение "", туда пишется один пробел (single space). А тип char() заполнится пробелами.


Q: В чем отличие полей char и varchar?

A: В результате экспериментов было выяснено, что если поле имеет признак NOT NULL, то тип VARCHAR занимает в таблице места столько, сколько значащих байт в строке (последние пробелы отрезаются), а CHAR занимает столько - сколько задано и добивает при необходимости пробелами. Если поле имеет признак NULL, то тип CHAR и VARCHAR ведут себя одинаково. Microsoft также утверждает, что доступ к полю CHAR идет быстрее, но на сколько (или во сколько) неизвестно.


Q: Есть такие данные (таблица tmpSample):
Column1 Column2 Column3
-------- -------- --------
10 А А
20 Б А
-5 А А
-15 В Б
25 В Б
Нужно выдать: комбинацию полей Column2 и Column3, сумму Column1, причем нужно выдать только положительные суммы. И самое главное: данные надо отсортировать по столбцу Column3. Менять выдаваемые данные и добавлять новые столбцы нельзя.
Т.е. должны получить на выходе:
Column2+Column3 Sum(Column4)
---------------- -------------
АА 5
БА 20
ВБ 10
Запрос получается таким:
select Column2+Column3, sum(Column1)
from tmpSample
group by Column2+Column3
having sum(Column1)>0
order by Column3
Проблема в том, что сортировка по столбцу Column3 запрещена - выдает ошибку SQL Server. Что делать?

A: Нужно добавить группировку по колонке Column3:
...
group by Column2+Column3, Column3


Q: В T-SQL есть оператор LIKE, который использует спец. символы:

  • '%' - любые один или несколько символов;
  • '_' - один любой символ.

А как искать строки, в которых присутствуют эти спецсимволы?

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

  • like '5[_]' - будут выбираться строки, содержащие '5_', а не '51', '5a' и т.д.;
  • like'ffff[%]' - будут выбираться строки, содержащие 'ffff%', а не 'ffffaaaa', 'ffff1' и т.д.;
  • like 'MB_an[_]' - будут выбираться строки, содержащие 'MB'+ любой символ+'an_'.
  • like '%[[]%' - будут выбираться строки, содержащие '['
  • like '%]%' - будут выбираться строки, содержащие ']'
  • like '%[[]]%' - будут выбираться строки, содержащие '[]'

Q: На MS SQL 6.5 выполняется truncate таблицы, после чего она заполняется новыми данными (несколько десятков тысяч записей) и скорость выполнения запросов с участием таблицы резко падает. Хотя до truncate количество записей в ней было примерно таким же и все необходимые индексы установлены. В чем дело и как исправить?

A: Уже замечено, что после truncate и заполнения таблицы SQL Server перестает использовать индексы, наложенные на эту таблицу. После закрытия текущего соединения с сервером и установки нового обычно все приходит в норму. (01/17/01)

Вверх

<<Назад

Главная| ИС.. | Моделирование | Проектирование |ТД | Разработка | Интерфейс | Статьи | Ссылки | Автор
DimDim SoftWare Мастерская Dr. dimdim Copyright 2003-2004
Администратор info-system@mail.ru
Последнее обновление 26-Дек-2003