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

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


Новости сайта "Упражнения по SQL (http://www.sql-ex.ru)" Выпуск 163 (9 ноября 2007 г.)

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

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

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

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

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


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

§ Глосование в рамках Премии Рунета вышло на заключительный этап. Пока мы держимся в ТОР 50, получив за неделю 300 голосов. Честно говоря, я приятно удивлен такой активности. Хочу отметить, что по новым правилам можно голосовать несколько раз; есть только одно ограничение - голосовать можно не чаще 1 раза в 24 часа. Голосование продлится до 27 ноября :-).

§ Fiolent обновил проверочную базу под 111-ю задачу.
Усилил проверку задачи 68 данными, предложенными Scorpion'ом.
Проверьте свои свои решения.

§ Лидеры затаились :-). Изменений в 20-ке на этой неделе не произошло. Еще два участника принялись за решение 143 задачи.

§ Продвинулись в рейтинге:
Kamin (задач 134, время 57.464)
Heromantor (132, 9.131)
Gleb (127,160.105)
Donald (121,5.430)

§ Претенденты на попадание в ТОР 100:
nebiros (120, 71.758)
Leshich (116, 99.072)
Johnny (110, 170.872)
nadush (107, 88.925)
pvv (106, 4.073)
Претендентов, естественно, больше, но выделяю тех, кто активно решал задачи в течение последних дней.

§ На этой неделе сертифицированы:
Kulibin (A07019687) [BK] - г.Харьков, Украина
Staatsanwalt (A07022022) [BK] - г.Киев, Украина

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

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

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

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

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

No Person Number of
Sel_ex
Last_Sel Number of
DML_ex
Scores Days Days_2 Days_3 S_3 LastSolved LastVisit
1 Белогурова К. (Katy_Ekb) 143 143 21 346 155 9.563 4.673 18 27 Oct 2007 06 Nov 2007
2 Креславский О.М. (Arcan) 143 143 21 346 269 17.514 7.720 18 26 Oct 2007 09 Nov 2007
3 Карасёва Н.В. (vlksm) 143 143 21 346 529 38.118 12.414 18 17 Oct 2007 09 Nov 2007
4 Голубин Р.С. (Roman S. Golubin) 143 143 21 346 795 69.101 43.885 18 22 Oct 2007 09 Nov 2007
5 Северюхин Ю.А. (Venser) 142 142 21 342 200 4.950 .655 14 19 Sep 2007 06 Nov 2007
6 Тарасов Д.Б. (Gavrila) 142 142 21 342 755 23.423 2.501 14 20 Sep 2007 09 Nov 2007
7 Солдатенков Ю.С. (SolYUtor) 142 142 21 342 490 17.853 2.695 14 20 Sep 2007 09 Nov 2007
8 Шептунов П.П. (Dzen) 142 142 21 342 279 8.186 3.499 14 02 Oct 2007 16 Oct 2007
9 Мурашкин И.В. (lepton) 142 142 21 342 544 15.800 5.539 14 18 Sep 2007 09 Nov 2007
10 Мальцев А.В. (Палкин) 142 142 21 342 422 49.738 7.690 14 13 Oct 2007 26 Oct 2007
11 Бураков С.Г. (burakov58) 142 142 21 342 974 51.702 19.814 14 30 Sep 2007 09 Nov 2007
12 Агапов В. (KERBEROS) 135 141 20 326 89 6.143 1.262 11 20 Nov 2006 27 Jul 2007
13 Кувалкин К.С. (Cyrilus) 139 141 20 334 1014 12.506 2.519 11 04 Sep 2007 07 Nov 2007
14 Зверев Д.Л. (dimzv) 135 141 20 326 1141 9.278 4.938 11 19 Dec 2006 22 Dec 2006
15 Войнов П.Е. (pаparome) 141 142 21 338 765 2.788 .049 10 28 Sep 2007 22 Oct 2007
16 Любченко В.А. (IAS56) 141 142 21 338 377 177.859 20.130 10 16 Sep 2007 09 Nov 2007
17 Васьков Е.В. (Johan) 138 140 21 332 402 12.733 11.402 7 25 Aug 2007 25 Aug 2007
18 Радар Ю.В. (inkerman) 139 143 21 332 60 5.354 .000 4 07 Oct 2007 08 Nov 2007
19 Валуев Д.И. (Fiolent) 139 140 21 332 1511 118.144 62.302 4 24 Oct 2007 09 Nov 2007
20 Юлдашев М.Р. (Snowbear) 139 139 21 331 791 4.162 .000 3 17 Sep 2007 08 Nov 2007

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

No surname n_sel sel_all sel_scores dml_scores scores rating last_visit
1 >Шуленин А. (Leshik) 67 69 130 0 130 781 09 Nov 2007
2 Башлачев В. (Viktar) 55 55 105 19 124 914 09 Nov 2007
3 >Гарин А.А. (aleshka) 49 49 93 3 96 1502 09 Nov 2007
4 Долгов В.В. (Dolgov.VV) 42 42 78 11 89 1718 08 Nov 2007
5 bbabay (Бизумный йошь !) 36 36 64 19 83 1877 08 Nov 2007
6 Водкин В.Н. (VasyaVodkin) 32 32 58 23 81 1924 08 Nov 2007
7 >Пахомова А.В. (alta) 44 44 81 0 81 1927 09 Nov 2007
8 >Марченко С.В. (Svem_Perm) 40 40 76 0 76 2104 09 Nov 2007
9 Аноним (Serg99) 33 33 61 9 70 2370 08 Nov 2007
10 Головишников К.В. (ImKot) 18 59 34 34 68 604 09 Nov 2007
11 >Городилов А.Ю. (GorA3000) 16 72 33 34 67 373 09 Nov 2007
12 Зорин М. (ZorinM) 35 35 64 0 64 2685 08 Nov 2007
13 >Корнилов Д.М. (dk1976) 29 59 63 0 63 631 09 Nov 2007
14 >Гавриленко С.В. (Energo) 32 32 60 0 60 2910 09 Nov 2007
15 >Сысоев А.В. (Sysa) 31 31 57 0 57 3109 09 Nov 2007
16 Иванов А. (asan_13) 30 30 56 0 56 3213 07 Nov 2007
17 >Селезнёв (Артём С.) 29 29 53 0 53 3505 09 Nov 2007
18 Velarde A.G. (chris_kiam) 28 28 43 9 52 3566 09 Nov 2007
19 >Belevich P. (Konigsberg) 22 29 47 0 47 3479 08 Nov 2007
20 Grom P. (Thunder) 23 56 45 0 45 1198 07 Nov 2007
21 Ермишкин А.Е. (Scratch) 26 26 44 0 44 4217 09 Nov 2007
22 Шадрина А. (Tenshi) 12 57 30 13 43 692 09 Nov 2007
23 >Кундеренко А.В. (Иные Миры) 22 22 34 9 43 4280 09 Nov 2007
24 Orekhovsky (knyaz) 17 31 42 0 42 3062 08 Nov 2007
25 >Tanzhov (Tanzhov) 25 25 41 1 42 4348 09 Nov 2007
26 >Туренко Ю.Л. (nebiros) 16 120 41 0 41 103 09 Nov 2007
27 Миронов А.Ю. (El) 18 51 40 0 40 1457 09 Nov 2007
28 >petrovich (svpetrovich) 24 24 40 0 40 4475 09 Nov 2007

Изучаем SQL

Вызов UDF, которые принимают таблицы с помощью оператора APPLY в SQL Server 2005

Tim Chapman (оригинал: Invoke UDFs that accept tables with SQL Server 2005's APPLY operator )
Перевод Моисеенко С.И.

Определенная пользователем функция (UDF) - объект базы данных, введенный в SQL Server 2000. Такие функции бывают двух типов: скалярнозначные и табличнозначные UDF. Скалярнозначная функция возвращает единственное значение при каждом вызове функции, в то время как табличнозначная UDF возвращает табличный набор записей, которой можно соединить с другими таблицами/результирующими наборами. Для более детального знакомства с табличнозначными функциями UDF, см.статью Артура Фаллера.

Ограничения

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

Сначала, я создаю таблицу и наполняю ее данными:

Листинг А

 

CREATE TABLE TempTable

(
      IDCol INT IDENTITY(1,1),
      Fld1 VARCHAR(10),
      Fld2 INT
)

GO

INSERT INTO TempTable(Fld1, Fld2) VALUES('tim1',1)
INSERT INTO TempTable(Fld1, Fld2) VALUES('tim2',2)
INSERT INTO TempTable(Fld1, Fld2) VALUES('tim3',3)
INSERT INTO TempTable(Fld1, Fld2) VALUES('tim4',4)
INSERT INTO TempTable(Fld1, Fld2) VALUES('tim5',5)
INSERT INTO TempTable(Fld1, Fld2) VALUES('tim6',6)
INSERT INTO TempTable(Fld1, Fld2) VALUES('tim7',7)
INSERT INTO TempTable(Fld1, Fld2) VALUES('tim8',8)
INSERT INTO TempTable(Fld1, Fld2) VALUES('tim9',9)
INSERT INTO TempTable(Fld1, Fld2) VALUES('tim10',10)

Go

 

Затем я создаю UDF, чтобы вытянуть данные из таблицы, как показано в листинге B:

Листинг В

 

CREATE FUNCTION udf_TestFunction
(
      @IDCol INT
)

RETURNS @Tim TABLE
(
      IDCol INT ,
      Fld1 VARCHAR(10),
      Fld2 int
)
AS
BEGIN
      INSERT INTO @Tim
      SELECT IDCol, Fld1, Fld2 FROM TempTable
      WHERE IDCol = @IDCol
      RETURN
END

GO

 

Это очень простая табличнозначная функция. Я передаю значение IDCol в функцию, и возвращаю строку, соответствующую IDCol в таблице TempTable. Я могу вызвать эту функцию с помощью простого запроса SELECT к UDF:

 

SELECT * FROM dbo. udf_TestFunction(5)

 

Я могу даже соединить эту функцию с таблицей TempTable для возвращения, например, такого набора записей:

 

SELECT *
FROM dbo.udf_TestFunction(5) f
INNER JOIN TempTable t ON f.IDCol = t.IDCol

 

Хотя это не практический пример, он иллюстрирует, что Вы можете соединить табличнозначную UDF с другими объектами (даже другими табличнозначными функциями). В SQL Server 2000 это работает, если параметры, которые Вы передаете в UDF, - скалярные переменные. SQL Server 2000 не поддерживает передачу значений строки в табличнозначную UDF в операции JOIN. Например, следующий запрос приводит к ошибке в SQL Server 2000:

 

SELECT *
FROM TempTable t
INNER JOIN dbo.fn_Test(t.IDCol)  f on t.ColID = f.ColID

 

Однако в SQL Server 2005 эта проблема решена с введением оператора APPLY.

Оператор APPLY

Оператор APPLY позволяет передать значение из таблицы в табличнозначную UDF как параметр. Однако порядок операции действительно имеет значение. Чтобы успешно применить оператор APPLY, Вы должны сначала записать таблицу, которую Вы хотите соединить с последующей UDF, в которую Вы будете передавать значение строки таблицы.

Есть два варианта оператора APPLY: CROSS APPLY и OUTER APPLY. Оператор CROSS APPLY подобен конструкции INNER JOIN в transact-sql. Возвращаемые результаты основаны на критериях, содержащихся в UDF, и возвращаются после того, как необходимые значения из внешней таблицы передаются в UDF как параметры. Вы легко можете переписать вышеприведенный запрос для SQL Server 2005, используя конструкцию CROSS APPLY следующим образом:

 

SELECT * FROM TempTable t CROSS APPLY dbo.fn_Test(t.IDCol)

 

Оператор OUTER APPLY подобен конструкции OUTER JOIN в transact-sql. Подобно OUTER JOIN, OUTER APPLY возвращает все строки из внешней таблицы и любые строки из табличнозначной UDF, которые удовлетворяют критериям для переменных, передаваемых в функцию. Чтобы использовать в своих интересах эти функциональные возможности, просто замените CROSS APPLY на OUTER APPLY в нашем предыдущем операторе:

 

SELECT * FROM TempTable t OUTER APPLY dbo.fn_Test(t.IDCol)

 

Конструкция CROSS APPLY (когда она относится к табличнозначной UDF) весьма подобна способу, которым работает коррелированый подзапрос. За дополнительной информацией относительно коррелированого подзапроса обратитесь к моей недавней статье. Похожесть состоит в том, что значение из внешнего запроса (в нашей ситуации это первая таблица) извлекается и передается в подзапрос, которым в этом случае является UDF.

Информация к размышлению

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

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

Очень частное мнение (комментарий к статье)

Joe Celko

Это очень частное мнение и, кажется, является попыткой подражать процедурному программированию.

Правильный ответ - никогда не передавать имя таблицы как параметр. Вы должны понять основную идею модели данных и что означает таблица применительно к модели данных. Вернемся к основам. Что такое таблица? Модель есть множество сущностей или отношений. КАЖДАЯ ТАБЛИЦА ДОЛЖНА БЫТЬ РАЗЛИЧНОГО ВИДА СУЩНОСТЬЮ. Когда Вы имеете много таблиц, которые моделируют ту же самую сущность, то Вы имеете файловую систему на магнитной ленте, написанную на SQL, а совсем не РСУБД.

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

20-09-2007

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

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

§ В рамках Премии Рунета проводится "народное голосование". Если вы считаете, что наш сайт заслуживает большей известности в рунете, проголосуйте за него. Для этого
- Пройдите по ссылке www.premiaruneta.ru/narod/vote/.
- Поставьте флажок напротив sql-ex.ru (ближе к концу списка).
- Поставьте флажок "Я согласен с правилами..." ниже списка участников.
- Нажмите кнопку Проголосовать!
Вы можете проголосовать сразу за нескольких участников.

§ Желающих поспособствовать популяризации сайта прошу проголосовать/поставить закладку в социальных сетях:
del.icio.us
dzone.com
Digg.com
Reddit.com
stumbleupon.com

Контакты

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

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

В избранное