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

Новости сайта "Упражнения по SQL" (http://www.sql-ex.ru) 219


Новости сайта "Упражнения по SQL (http://www.sql-ex.ru)"

Выпуск 219 от 06 декабря 2008 г.

Новым посетителям сайта

SQL Exercises Сайт посвящен изучению языка, с помощью которого осуществляется взаимодействие с реляционными (и не только) СУБД. Суть обучения состоит в выполнении заданий на написание запросов к учебным базам данных; при этом система контролирует правильность выполнения заданий. В настоящее время реализованы все операторы подъязыка манипуляции данными (DML), которые включают в себя оператор извлечения данных SELECT, а также операторы модификации данных - INSERT, DELETE и UPDATE.

Мы надеемся, что справочного материала сайта окажется достаточно для самостоятельного обучения. Кроме того, свои решения вы можете обсудить на форуме сайта. Опытных же специалистов приглашаем проверить (продемонстрировать) свое мастерство и принять участие в соревновании, обеспечиваемом рейтинговой системой учета времени выполнения заданий. Фактически, рейтинг ведется на втором этапе тестирования, который начинается сейчас после решения 50-й задачи первого этапа. При подсчете рейтинга каждого участника отбрасывается один самый худший показатель среди всех решенных им упражнений.

Демонстрация плана выполнения запроса и сравнительная оценка эффективности решений поможет вам освоить принципы оптимизации запросов, которые пригодятся на третьем рейтинговом этапе, который начинается после 138 задачи.

Имеется возможность получить сертификат по SQL DML при выполнении определенного количества заданий.


Новости сайта

§ Добавил проверочных данных (сообщения от noname) для задач 18 (DML) и 56 (SELECT).

§ Изменения среди лидеров (решенные за неделю задачи третьего этапа):
8. Ozzy (146)
10. rem (144-146, 148, 150)
14. anddros (144)
24. GreyC (140, 141)
29. Umrikhina (142)

§ Новые лица в ТОР 100 и вернувшиеся туда:
74. AlShin (задач 128, время 8.485)
90. cmalex (126, 68.633)
94. enull (125, 31.817)

§ Продвинулись в рейтинге:
45. orange (138, 15.858)
60. glassman (133, 50.070)
76. Балуткин (129, 381.484)
93. Ashton (125, 26.378)

§ Продвижение ближайших претендентов на попадание в ТОР 100:
104. breezemaster1 (124, 35.468)
105. Чих (124, 66.282)
121. Romul_T (121, 49.968)
122. Nariman Kurbanoff (121, 79.611)
138. noname (118, 9.761)
156. Edward_rost (115, 130.274)
168. Vasilko (126, 7.514)

§ На этой неделе сертифицированы:
AlexandrB (A08040760) [BK] - г.Москва, Россия
Gluttton (A08033930) [BK] - г.Киев, Украина
Cerebral (A08040780) [BK] - г.Москва, Россия
enull (B08039096) [AR] - г.Москва, Россия

§ Число подписчиков - 3821

Число участников рейтинга - 19870

Число участников второго этапа - 1621

Число участников третьего этапа - 44

Сертифицировано на сайте - 343

Лучшие результаты (ТОР 20)

No Person Number of
Sel_ex
Last_Sel Number of
DML_ex
Scores Days Days_2 Days_3 S_3 LastSolved LastVisit
1 Никотин В.М. (@Nikotin) 150 106 21 363 96 8.329 3.751 40 01 Dec 2008 05 Dec 2008
2 Сальников С.А. ($erges) 150 106 21 363 279 3.496 3.824 40 01 Dec 2008 05 Dec 2008
3 Креславский О.М. (Arcan) 150 106 21 363 668 51.995 39.373 40 28 Nov 2008 05 Dec 2008
4 Карасёва Н.В. (vlksm) 150 106 21 363 936 78.003 49.585 40 27 Nov 2008 05 Dec 2008
5 Печатнов В.В. (pvv) 147 149 21 354 357 30.856 17.490 36 10 Oct 2008 05 Dec 2008
6 Селезнёв А.С. (Артём С.) 146 149 21 351 322 38.511 29.235 36 25 Sep 2008 21 Nov 2008
7 Держальцев В.А. (MadVet) 138 146 21 335 1257 60.806 28.482 28 24 Sep 2008 06 Oct 2008
8 Зотов П.Г. (Ozzy) 142 146 21 342 264 61.179 78.826 28 29 Nov 2008 05 Dec 2008
9 Любченко В.А. (IAS56) 137 146 21 334 615 403.410 373.617 28 11 May 2008 01 Dec 2008
10 Муллаханов Р.Х. (rem) 146 150 21 349 448 3.285 1.773 26 01 Dec 2008 05 Dec 2008
11 Мурашкин И.В. (lepton) 142 148 21 340 950 43.609 33.116 26 28 Oct 2008 10 Nov 2008
12 Голубин Р.С. (Roman S. Golubin) 141 145 21 337 1122 93.051 58.822 25 13 Sep 2008 01 Dec 2008
13 Nikolaenko A.V. (Shadow77) 143 147 21 341 436 77.515 14.010 23 22 Oct 2008 24 Oct 2008
14 Дроздков А.Н. (anddros) 144 144 21 344 189 4.525 1.153 21 02 Dec 2008 05 Dec 2008
15 Солдатенков Ю.С. (SolYUtor) 139 146 21 333 819 22.624 6.102 20 14 Aug 2008 23 Oct 2008
16 Белогурова К. (Katy_Ekb) 134 143 21 323 552 10.673 4.673 18 27 Nov 2008 02 Dec 2008
17 Егоров А.Б. (ABEgorov) 138 144 21 331 180 12.906 8.815 18 03 Aug 2008 12 Aug 2008
18 Войнов П.Е. (pаparome) 140 146 21 332 1125 3.129 .213 17 22 Sep 2008 07 Oct 2008
19 Тарасов Д.Б. (Gavrila) 142 69 21 337 1189 26.474 3.677 17 27 Nov 2008 05 Dec 2008
20 iglbeat (iglbeat) 138 145 21 330 360 34.591 15.225 17 08 Aug 2008 25 Aug 2008

Лучшие результаты за неделю

No surname n_sel sel_all sel_scores dml_scores scores rating last_visit
1 Соколов М.Ю. (candidate71) 53 53 97 0 97 1664 03 Dec 2008
2 Frig S. (Afrikaan) 53 53 97 0 97 1665 05 Dec 2008
3 Шарипов З.Б. (Зафар) 29 53 59 30 89 979 05 Dec 2008
4 >Кузнецов В.С. (herrRo) 24 55 43 31 74 917 05 Dec 2008
5 >Волосухин С.С. (TRyaSS) 37 37 72 0 72 2755 05 Dec 2008
6 >Де Вольф Л. (Баронесса) 18 41 45 26 71 1423 05 Dec 2008
7 Сухарев Р. (Jessi) 25 25 47 15 62 3465 01 Dec 2008
8 >Пехтерев Е. (E_Pekhterev) 32 32 61 0 61 3570 05 Dec 2008
9 Аксёнов И.Н. (Voyager) 11 46 20 34 54 1115 04 Dec 2008
10 >Gadde S. (Sirisha) 21 21 37 17 54 4201 05 Dec 2008
11 >Самородов Ф.А. (Specialist) 20 29 43 0 43 3636 05 Dec 2008
12 khurtsilava G. (gigi23) 22 22 37 1 38 6025 05 Dec 2008
13 Kochegarov Y. (Yurey) 20 25 37 0 37 5644 04 Dec 2008
14 >Tkach A. (andreytkach) 16 33 36 0 36 3609 05 Dec 2008
15 >Белов О.И. (Xoma) 10 31 28 7 35 3265 05 Dec 2008
16 Пестерев (Анатолич) 23 23 35 0 35 6313 04 Dec 2008
17 maksimov (kix) 19 34 32 0 32 4510 04 Dec 2008
18 Немо (Log) 0 67 0 31 31 605 04 Dec 2008
19 >Mostovoy (PahanSP) 12 33 31 0 31 2298 05 Dec 2008
20 >b V. (banala) 17 17 25 6 31 6973 05 Dec 2008

Изучаем SQL

Массивы и списки в SQL Server 2005 (начало в вып.217, 218)

Erland Sommarskog (оригинал: Arrays and Lists in SQL Server 2005 )
Перевод: Моисеенко С.И.

Общие вопросы

Интерфейс

Большинство методов, которые я представлю тут, упаковано в функции, которые принимают входной параметр, являющийся списком значений, а возвращают таблицу, например:

CREATE FUNCTION list_to_table (@list nvarchar(MAX))
   RETURNS @tbl TABLE (number int NOT NULL) AS

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

Входные параметры

В этой статье входной параметр всегда имеет тип данных nvarchar(MAX). Это новый тип данных в SQL 2005, который может содержать до 2 Гб данных, как старый тип данных ntext, но при этом nvarchar (MAX) не имеет многих причуд типа ntext.

Я остановился на этом типе, поскольку хочу сделать функции настолько общими, насколько это возможно. При использовании nvarchar функции могут обрабатывать входные данные в кодировке Unicode, при этом MAX не накладывает ограничения на размеры входных параметров. При использовании nvarchar (4000) они начинали бы давать неправильные результаты на больших размерах входных данных.

Однако за такой выбор приходится платить производительностью. Если Вы используете коллацию SQL, то должны знать, что varchar дает лучшую производительность. А некоторые операции выполняются медленнее с типами данных MAX. Таким образом, если Вы знаете, что ваши списки никогда не будут превышать 8000 байтов, и Вы будете работать только с вашей кодовой страницей ANSI, и Вам требуется максимально возможная производительность, не стесняйтесь использовать varchar (8000) вместо этого типа.

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

Выходная таблица

Функции возвращают таблицу. Для всех методов, я включил одну функцию, возвращающую таблицу строк, а для некоторых методов еще и функцию, возвращающую таблицу целых чисел. (Что, вероятно, будет наиболее общим типом данных для такого типа списков.) Если Вы имеете список целых чисел и функцию, которая возвращает строки, Вы можете поступить следующим образом:

SELECT ...
FROM   tbl t
JOIN   list_to_table(@list) l ON t.id = convert(int, t.str)

Аналогично можно поступить с другими типами данных. Вы можете легко клонировать версию функции, которая содержить встроенное преобразование. (Однако загляните в раздел Надежность для уверенности.)

Тип данных, который требует большего внимания - строки. Что возвращать nvarchar или varchar? Очевидно, когда Вы работаете с данными Unicode, следует возвращать строки типа nvarchar. Это может заставить всегда возвращать nvarchar, но по причинам, которые я рассмотрю в разделе производительности, следует удостовериться в том, что получаете строку varchar, когда выполняется соединение со столбцом varchar. Для некоторых методов возвращаемая таблица содержит сразу два столбца с типами varchar и nvarchar соответственно.

В некоторых функциях, я также возвращаю позицию в списке для элементов списка. Это может оказаться удобным, когда Вы имеете два или более списков, которые являются горизонтальным разбиением того же самого источника. В результате можно поступить, например, так:

INSERT tbl(id, col2, col3)
   SELECT a.number, b.str, c.str
   FROM   intlist_to_table(@list1) a
   JOIN   charlist_to_table(@list2) b ON a.listpos = b.listpos
   JOIN   charlist_to_table(@list3) c ON a.listpos = c.listpos

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

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

Надежность

Нельзя отрицать, что парсинг строк несколько рискован. Пока входные параметры подчиняются правилам, все идет прекрасное, но что происходит, если это не так? Хорошая функция список-в-таблицу сможет защитить Вас от некоторых несчастных случаев, но не от всех. Ниже несколько ситуаций, которые нельзя упускать из виду.

Разделитель на входе

Скажем, что у нас есть несколько названий городов, например: Berlin, Barcelona, Frankfurt (Main), Birmingham, K?benhavn. Из них Вы хотите составить разделенный запятыми список, который Вы передаете в функцию список-в-таблицу. С приведенными выше названиями, все работает прекрасно, но затем некий шутник вводит Dallas, TX. Oh-oh.

Есть несколько способов избежать этой проблемы. Так, можно использовать разделитель, который вряд ли появится во входных данных, например, управляющий символ. Многие программы заключают строки в кавычки, т.е. список выглядел бы так: "Berlin","Barcelona" и т.д. Этот последний формат не поддерживается ни одной из моих функций, но Вы можете немного доработать некоторые из них для учета и такого варианта.

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

Когда Вы работаете со списками целых чисел, это, весьма вероятно, не будет вызывать проблем.

Дополнительный пробелы

Если Вы имеете такой список на входе:

ALFKI, VINET, BERGS,FRANK

Хотите ли вы, чтобы дополнительные пробелы были включены в данные, возвращаемые функцией list-to-table? Вероятно, нет. Все функции в этой статье удаляют начальные и конечные пробелы в элементах списка. Однако есть некоторые методы, где это не возможно. (Или, более точно, они не в состоянии обработать несогласованные пробелы.)

Недопустимый ввод

Скажем, у нас есть функция, которая принимает список целых чисел. Что произойдет, если на входе будет такой список: 9, 12, a, 23, 12?

Без специального кодирования SQL Server сообщит вам об ошибке преобразования, и выполнение пакета будет прервано. Если Вы предпочитаете, можно добавить проверки в вашу функцию, чтобы недопустимые значения игнорировались или заменялись на NULL.

Чтобы не отвлекаться на посторонние детали, я не добавлял такие проверки в функции для этой статьи.

Пустые элементы

Что, если на вход вашей функции, которая принимает список целых чисел, поступит: 9, 12,, 23, 12. Как следует интерпретировать двойную запятую? Если Вы выполните простое преобразование, то получите 0, что не очень хорошо. Было бы лучше вернуть NULL или просто не учитывать этот элемент. (Сгенерировать ошибку? Вы не можете генерировать ошибки в функциях.)

В некоторых функциях этой статьи я применяю один прием, позволяющий избежать всех этих проблем посредством использования пробела в качестве разделителя. Но так как T-SQL не предоставляет функции для обработки внутренних пробелов, данный подход не лишен проблем. Для методов, которые основываются на логике традиционного программирования, Вы можете легко обработать множественные пробелы, но для методов, который используют комбинацию charindex и теоретико-множественный подхода, Вы вынуждены отфильтровывать пустые элементы в предложении WHERE. (Чего я не делаю в этой статье.)

(Продолжение следует...)

Полезная информация

§ Приглашаем вас посетить новый проект - Интерактивный учебник по SQL.
   Ресурс позиционируется как "справочное обеспечение" для сайта SQL-EX.RU, но может использоваться и независимо от него.

§ Онлайновый выпуск рассылки можно почитать на сайте.

§ Все статьи, публикуемые в рассылке, затем выкладываются на сайте Книги и статьи по SQL.

§ Хотите поддержать проект? Вот инструкция по применению. :-)

Контакты

По всем вопросам, связанным с функционированием сайта, проблемами при решении упражнений, идеями вы можете обращаться к Сергею И.Моисеенко msi77[@]yandex.ru. Вы также можете предложить свои задачи для публикации на сайте.

Подписка Subscribe.Ru
Новости сайта "Упражнения по SQL"

В избранное