МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования ‹‹КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ›› (ФГБОУ ВПО ‹‹КубГУ ››) Кафедра вычислительных технологий ПОИСКОВЫЙ РОБОТ, ОРИЕНТИРОВАННЫЙ НА ИНФОРМАЦИЮ О ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ Л.А.Захарова Краснодар 2014 СОДЕРЖАНИЕ ВВЕДЕНИЕ .............................................................................................................. 2 1 Приложение «поисковый робот»...................................................................... 4 1.1 Архитектура приложения .............................................................................. 5 2 Оценка результатов поиска ................................................................................. 6 2.1 Алгоритм оценки........................................................................................... 6 2.2 Средства реализации...................................................................................... 6 2.3 Реализация алгоритма оценки ...................................................................... 7 3 Планирование индексации ................................................................................ 11 3.1 Планировшик ................................................................................................ 11 3.2 Написание скриптов для запуска планирования ...................................... 11 4 Интеграция приложения в сайт кафедры вычислительных технологий ...... 13 4.1 Настройка сервера....................................................................................... 13 Заключение ............................................................................................................ 15 Список использованных источников .................................................................. 16 Приложение А Программный код ...................................................................... 17 Приложение В Результаты работы программы ................................................ 24 1 ВВЕДЕНИЕ В связи с бурным развитием сети Интернет, с каждым днем все более актуальной становится проблема автоматизированного сбора и анализа информации, размещаемой на различных веб-ресурсах. Еще в начале 90-х годов прошлого представляла собой огромное столетия количество слабо Всемирная паутина структурированной информации, производить поиск в которой стало для человека практически непосильной задачей. Именно в это время стали появляться первые разработки в сфере автоматизированных агентов, облегчающих задачу поиска необходимой информации в паутине. Основной частью таких систем является поисковый робот — программный комплекс, осуществляющий навигацию по веб-ресурсам и сбор информации для базы данных приложения-агента. В настоящее время существует большое количество поисковых систем, которые являются неотъемлемой частью Интернета. Работу таких систем обеспечивает целый комплекс программ. Их устройство, как правило, является коммерческой тайной. При помощи поисковых роботов сервис анализирует информацию из HTML множества сайтов и хранит её для будущих запросов. Роботы замечают каждую ссылку на сайте. Содержание каждой страницы соответствующим образом индексируется — система распознаёт отдельные слова и целые выражения из заголовков, текстов или специально проставленных метаданных. После ввода поискового запроса система сверяется с соответствующим индексом и предоставляет выдачу наиболее релевантных ссылок. Объектом исследования данной курсовой работы является поисковый робот. Целью работы является расширение поиска в приложении, создание «самообучающейся системы», написание программы, которая будет оценивать сайты и ,исходя из прошлого опыта, присваивать сайту оценку 2 .Сайты с наивысшими оценками добавляются в список сайтов, используемых приложением «поисковый робот» таким образом, программа использует и пополняет базу сайтов, наиболее важных с точки зрения цели поиска. Доступ к программе должен быть обеспечен на сайте кафедры вычислительных технологий. 3 1 Приложение «поисковый робот» В процессе выполнения курсовой работы в прошлом семестре было создано приложение «поисковый робот». Поисковый робот (web crawler, краулер) – программа, являющаяся составной частью поисковой системы и предназначенная для перебора страниц Интернета c целью занесения информации о них в базу данных поисковика. По принципу действия паук напоминает обычный браузер. Он анализирует содержимое страницы, сохраняет его в некотором специальном виде на сервере поисковой машины, которой принадлежит, и отправляется по ссылкам на следующие страницы. Порядок обхода страниц, частота визитов, защита от зацикливания, а так же критерии выделения значимой информации, определяются поисковыми алгоритмами. В донном приложении были реализованы все основные традиционной процедуры поиска: • Краулинг • Синтаксический разбор • Анализ • Индексирование • Поиск Робот может загружать страницы из Интернета или из локальной файловой системы. Кроме HTML – документов он может обрабатывать документы текстового процессора Microsoft Word. Каждый документ сохраняется в отдельном файле; робот использует для этого обычный текстовый формат. 4 этапы 1.1 Архитектура приложения Базовыми для приложения являются следующие классы: • Класс ScheduledIndexer 1) извлечение данных и выполнение их синтаксического разбора. 2)Удаление существующего индекса 3)Создание нового индекса. ( Index – Writer) • Класс RobotLauncher 1)Поиск по существующему индексу (IndexSearcher) 2)Преобразование результатов поиска в формат XML Класс Server ((для организации веб-сервиса) 1)Запуск веб-сервера на определенном порту.(прослушивание порта) 2)Запуск на веб-сервере сервер XMLRPC. 5 2 Оценка результатов поиска В процессе выполнения работы требовалось выполнить расширение поиска. Изначально у нас было несколько сайтов, которые задавались вручную, по которым выполнялся поиск. Для реализации оценки использовался серверный язык PHP, было установлено соединение с базой данных (MySql WorkBench). 2.1 Алгоритм оценки . Веб-сервис, созданный на основе приложения «поисковый робот» работает следующим образом: В строке запроса (на клиенте) вводится искомое слово, которое отправляется на сервер, где выполняется поиск, и с сервера возвращаются результаты. Далее результаты выводятся в браузер. В поле для вывода результатов были добавлены 2 кнопки с символами «+» (увеличить рейтинг сайта) и «-» (понизить рейтинг сайта). После ознакомления с информацией, предоставленной по ссылке, пользователь может оценить была ли полезной для него информация, предоставленная данным источником, нажав одну из кнопок. Оценки пользователей учитываются и ,впоследствии, сайты, которые набирают определенное число голосов за поднятие рейтинга, добавляются в список тех сайтов, по которым приложение «поисковый робот» выполняет индексацию и поиск. Таким образом, происходит расширение поиска. 2.2 Средства реализации Для реализации оценки использовался серверный язык PHP,JavaScript (библиотека Jquery), было установлено соединение с базой данных , используя MySql WorkBench. MySQL Workbench — инструмент для визуального проектирования баз данных, интегрирующий проектирование, моделирование, создание и эксплуатацию БД в единое бесшовное окружение для системы баз данных MySQL. 6 Базы данных MySql делятся на таблицы, содержимое которых состоит из строк 2.3 Реализация алгоритма оценки Алгоритм основывается на базе данных, организованной на платформе MySql WorkBench. Здесь была создана схема (Sites), включающая таблицу ( SitesRating) и несколько хранимых процедур. В таблице были организованы следующие столбцы : • Domain - доменное имя сайта • Rating – рейтинг, соответствующий сайту • isAdded – флаг, показывающий добавлен ли уже данный сайт в список сайтов, по которым выполняется поиск. Пользователь вводить слово для поиска и нажимает кнопку подтверждения запроса. Далее происходит передача параметра в приложение (на сервер), используется технология XML-RPC (Extensible Markup Language Remote Procedure Call — XML-вызов удалённых процедур) , после чего приходит ответ от сервера, содержащий результат, xml файл с заголовками статей и ссылками на них .Клиент получает xml с результатами работы приложения и извлекает данные из него в массив .Каждый элемент массива включает в себя: • Ссылку на статью; • Заголовок статьи: • Домен (предварительно полученный из ссылки на статью, использованием всторенной функции PHP pasrse_url()) • Поле (used), которое показывает, содержится ли данный домен в списке сайтов, по которым ведется поиск, ( по умолчанию false). 7 После того, как был сформирован данный массив, предполагалось организовать вывод результатов поиска в порядке убывания рейтингов доменов, на которых они расположены. Для этого была реализована специальная функция сортировки (SitesSort).Параметрами этой функции является массив сайтов, полученный на предыдущих шагах, и еще один массив, содержащий все домены, содержащиеся в базе данных, расположенные в порядке убывания их рейтингов, (формирование данного массива выполняется в функции GetRatedDomains())В функции сортировки сайтов SitesSort создаются три массива: • массив, содержащий домены с положительным рейтингом (Positive) • массив, содержащий домены с нулевым рейтингом (Zero) • массив ,содержащий домены с отрицательным рейтингом (Negative) Далее в цикле просматривается каждый элемент массива сайтов (Sites) и проверяется на равенство элементами с уже отсортированного массива всех сайтов , полученного в функцией GetRatedDomains(). И ,если равенство было найдено, то соответствующий элемент массива добавляется в один из массивов Positive, Negative или Zero (в зависимости от того, какой рейтинг соответствует данному сайт –положительный, отрицательный или нулевой).Кроме того, в функции SitesSort – заполняются поля used результирующего массива Sites .Результатом работы функции является один массив, сформированный из трех (Positive, Zero, Negative) с использованием функции языка PHP array_merge(). На следующем шаге производится вывод результатов (уже отсортированных) на страницу в следующем виде: 8 Рисунок 1 – Представление результатов Рядом с заголовком статьи находится ссылка с надписью перейти (переход на сайт со статьей) и две кнопки с символами (+) и (-), которые обозначают увеличить и убрать рейтинг, соответственно. По нажатию на эти кнопки, вызывается процедура (RateAdd), написанная на языке JavaScript.В данной процедуре формируется Ajax – запрос ( осуществляет запрос к серверу без перезагрузки страницы) , который передает специальному php скрипту (rate_maker.php) данный домен и число, на которое нужно увеличить рейтинг. ( -1 или 1) в зависимости от того, какая была нажата кнопка «+» или «-» . В php-скрипте rate_maker.php реализован вызов хранимых процедур схемы Sites. Хранимая процедура - это способ инкапсуляции повторяющихся действий. В хранимых процедурах можно объявлять переменные, управлять потоками данных, а также применять другие техники программирования. Для реализации данного алгоритма оценки результатов были созданы хранимая процедура – RatingProc и функция NeedToAdd. 9 Хранимая процедура RatingProc. Получает параметры: домен (P_Domain) и число, на которое предполагается изменить значение рейтинга в базе данных (P_Rating). Число вхождений заданного домена подсчитывается и сохраняется в переменную (L_HasDomain), после чего проверяется, если значение этой переменной ноль, то в таблицу базы данных вставляется строчка с новым доменом, в противном случае поле рейтинга, соответствующее заданному домену, обновляется (к нему прибавляется значение параметра P_Rating). Хранимая функция NeedToAdd.Функция определяет, нужно ли добавлять данный домен к списку сайтов (в приложении «поисковый робот»), по которым выполняется поиск. Выполняется проверка того, что рейтинг сайта достиг значения, большего 50, и сайт еще не был добавлен в список сайтов приложения. И ,если значение рейтинга сайта больше 50 и сайт еще не добавлен в основной список, функция возвращает 1, иначе 0. Вызов хранимой процедуры RatingProc и хранимой функции NeedToAdd производится в скрипте Rate_maker . И, если параметр, возвращаемый функцией равен 1, то производится XML-rpc запрос,к приложению, которой удаленно вызывает метод класса RobotLauncher (AddUrlToSearch) и передает в него параметр – домен, который нужно добавить в список сайтов. Добавление сайта в список тех, по которым предполагается выполнять поиск, реализовано на сервере в процедуре AddUrlToSearch. В текстовый файл (urls.conf) добавляется строчка с адресом. Для выполнения поиска, основываясь на файле urls.conf, в класс FetchAndProcess программы был добавлен метод (setConfigUrls()),в котором производится получение адресов из файла. На следующем шаге функция AddUrl() преобразует строку из файла к виду url-адреса. 10 3 Планирование индексации В приложении «поисковый робот» разделены (т.к. индексация этапы индексации и поиска занимает большое количество времени, в зависимости от глубины поиска и кол-ва извлекаемых документов). В ходе выполнения данной курсовой работы также была поставлена задача планируемого запуска индексации. То есть индексация должны запускаться через определенные промежутки времени. 3.1 Планировшик Сron — демон-планировщик задач в UNIX-подобных операционных системах, использующийся для периодического выполнения заданий в определённое время. Регулярные действия описываются инструкциями, помещенными в файлы crontab и в специальные директории. 3.2 Написание скриптов для запуска планирования Вash (Bourne shell) — again усовершенствованная и модернизированная вариация командной оболочки Bourne shell. Одна из наиболее популярных современных разновидностей командной оболочки UNIX. Особенно популярна в среде Linux, где она часто используется в качестве предустановленной командной оболочки. Bash — это командный процессор, работающий, как правило, в интерактивном режиме в текстовом окне. Bash также может читать команды из файла, который называется скриптом (или сценарием). Как и все Unixоболочки, он поддерживает авто дополнение названий файлов и папок, подстановку вывода результата команд, переменные, контроль за порядком выполнения, операторы ветвления и цикла. Ключевые слова, синтаксис и другие основные особенности языка были заимствованы из sh. Для запуска индексации был написан скрипт, в котором выполняются следующие действия: • запуск индексации 11 • удаление старых результатов поиска • добавление папок с новыми результатами поиска Сервер запускается вручную и работает постоянно («прослушивает» определенный порт). На следующем пользовательской таблицы шаге было произведено редактирование crontab (планировщик cron).В нее добавилась запись для скрипта, созданного на предыдущем шаге. 12 4 Интеграция приложения в сайт кафедры вычислительных технологий В процессе выполнения курсовой работы была поставлена задача : обеспечить доступ к приложению с сайта кафедры вычислительных технологий. На сервере была создана виртуальная машина linux (debian 7.1). Debian - операционная система, состоящая из свободного ПО с открытым исходным кодом. В настоящее время Debian GNU/Linux — один из самых популярных и важных дистрибутивов GNU/Linux, в первичной форме оказавший значительное влияние на развитие этого типа ОС в целом. Debian может использоваться как в качестве операционной системы для серверов, так и для рабочих станций.В данном случае операционная система использовалась в качестве сервера. 4.1 Настройка сервера Для настройки сервера (oc Debian) необходимо было установить следующие компоненты: PHP (Hypertext Preprocessor — «PHP: препроцессор гипертекста»; первоначально Personal Home Page Tools[4] — «Инструменты для создания персональных веб-страниц»; произносится пи-эйч-пи) —скриптовый язык[5] программирования общего назначения, интенсивно применяемый для разработки веб-приложений. В настоящее время поддерживается подавляющим большинством хостинг-провайдеров и является одним из лидеров среди языков программирования, применяющихся для создания динамических веб-сайтов[6]. Apache — свободный веб-сервер. Apache является кроссплатформенным ПО, поддерживает операционные системы Linux, BSD, Mac OS, Microsoft Windows, Novell NetWare, BeOS.Основными достоинствами Apache считаются надёжность и гибкость конфигурации. Он позволяет подключать внешние модули, 13 использовать СУБД для аутентификации пользователей, модифицировать сообщения об ошибках и т. д. Поддерживает IPv6. Java — объектно-ориентированный язык программирования, разработанный компанией Sun Microsystems. Характерная особенность языка программирования Java – независимость от архитектуры компьютера .Компилятор генерирует объектный файл , формат которого не зависит от архитектуры компьютера. Скомпилированная программа может выполняться на любых процессорах ; для ее работы необходима лишь исполняющая система Java.Код, генерируемый компилятором Java , называется байтовым кодом. Он разработан таким образом, чтобы на любой машине его легко было интерпретировать, либо в процессе работы перевести в набор команд, ориентированных на конкретный процессор. Рисунок 2 – Схема работы веб-сервиса 14 Заключение В ходе выполнения данной курсовой работы, был реализован алгоритм оценки результатов, полученных поисковой процедурой, выполненной в прошлом семестре. После просмотра статьи пользователь может оценить, насколько полезной для него была информация. Также был реализован вебсервис, на основе технологии xml-rpc. Таким образом, программа использует и пополняет базу сайтов, наиболее важных с точки зрения цели поиска. В результате чего происходит расширение поиска. В перспективе работы над приложением, усовершенствование алгоритма оценки результатов поиска, изучение других подходов к оценке результатов, с целью нахождения оптимального. 15 Список использованных источников 1. Марманис Х., Бабенко Д. Алгоритмы интеллектуального интернета. Передовые методики сбора, анализа и обработки данных. //СПб.:СимволПлюс, - 2011, - С. 480. 2. Ноутон П., Шилдт Г. Java™ 2. // СПб.:БХВ-Петербург, - 2008, - С. 1072. 3. Уварова А. Основы программирования на Java. //Краснодар.:Кубанский гос. ун-т, - 2010, - С.52 4. Прохоренок Н.А. HTML, JavaScript, PHP,MySQL.Джентельменский набор Web-мастера. // СПб.:БХВ-Петербург, - 2012, - С.912 5. Бенедетти Р.,Крэнли Р. Изучаем работу с jQuery. //Спб.:Питер, - 2012, С.512. 6. Сьерра К. Изучаем Java. //М:Эксмо, - 2013, - С.720. 16 Приложение А Программный код <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <meta content="http-equiv" contentType="text/html;charset=utf-8" /> <title>Поисковый клиент.</title> <link rel='stylesheet' type='text/css' href='CSS/style.css'> <script type="text/javascript" src="jquery-2.0.3.min.js"></script> <script language="JavaScript"> var flag = 0; $(document).ready(function() { $("#startField").show(); $("#TopPos").show(); $( "#button3" ).click(function() { $("#startField").hide(); $("#TopPos").show(); }); //if (flag == 0) //{ //$("#startField").show(); //$("#TopPos").hide(); //} else //{ // $("#startField").hide(); // $("#TopPos").show(); // //} $( "#button1" ).click(function() { // alert( "Handler for .click() called." ); $("#TopPos").show(); $("#startField").hide(); flag = 1; }); $( "#button2" ).click(function() { //x alert( "Handler for .click() called." ); $("#ServiceNote").show(); }); }); function RateAdd(domain, rating) { $.ajax({ url : "rate_maker.php", type : "POST", data : {domain : domain, rate : rating}, success : function(res) { 17 alert("Спасибо! Ваше мнение важно для нас."); } }); } </script> </head> <body> <div id ="TopPos"> </br> <form method="post" action=""> <star class="headline2">ПОИСК НАУЧНЫХ СТАТЕЙ</star> <input type = "text" class = "input" placeholder="Слово" name = "word" id = word /> <input type = "submit" id="button2" value = "Искать"/> <star class="headline3">SCIENTIFIC PAPERS SEARCH</star></form></br></br> </div> </form> <DIV id = "ServiceNote"> </DIV> <?php if($_SERVER["REQUEST_METHOD"]=="POST") { $Phrase = $_POST["word"]; $context = stream_context_create(array('http' => array( 'method' => "POST", 'header' => "Content-Type: text/xml", 'content' => CreateXMLRPC("RobotLauncher.Search", $Phrase) ))); $file = file_get_contents("http://127.0.0.1:4444/xmlrpc", false, $context);//virtual //$file = file_get_contents("http://192.168.56.1:4444/xmlrpc", false, $context);//intelig idea //print($file); $respXml = new SimpleXMLElement($file); $xml = new SimpleXMLElement($respXml->xpath("//value")[0]); $RatedSites = GetRatedDomains(); $Sites = array(); foreach ($xml->result as $res) { $dom = parse_url(trim($res->link), PHP_URL_HOST); //printf("<tr><td>%s</td><td><a href=\"%s\">Перейти</a></td></tr>\n",$res->t, $res->link); array_push($Sites,array("url" => $res->link, "content"=> $res->t, "domain" => $dom, "used" => false)); } //print_r($RatedSites); //print_r($Sites); $Sites = SitesSort($Sites, $RatedSites); printf("<p></br>В целях улучшения качества результатов поиска, просим Вас оценить ссылку, поставив \"+\", если информация по ссылке была полезной, или \"-\" в противном случае.</br></br> </p>"); ?><table><? 18 for($i = 0; $i < count($Sites); $i++) { printf("<tr class = 'output'><td>%s</td><td><a href=\"%s\" target=\"_blank\">Перейти</a></td>". "<td><span class=\"span_button-small\" onclick='RateAdd(\"%s\", 1)'>+</span></td>". "<td><span class=\"span_button-small\" onclick='RateAdd(\"%s\", -1)'>-</span></td></tr>" ,$Sites[$i]["content"], $Sites[$i]["url"], $Sites[$i]["domain"], $Sites[$i]["domain"]); } ?></table><? } function CreateXMLRPC($ClassName, $SearchWord) { $request = new SimpleXMLElement("<methodCall/>"); $request->addChild("methodName",$ClassName); $params = $request->addChild("params"); $param = $params->addChild("param"); $value = $param->addChild("value"); $value->addChild("string",$SearchWord); return $request->asXML(); } function GetRatedDomains() { if($db = mysqli_connect("localhost", "RobotUser", "123", "Sites","3306")) { $db->select_db("Sites"); $queryString = "Select Domain, Rating from SitesRating order by Rating desc"; if($stmt = $db->prepare($queryString)) { $arr = array(); if($stmt->execute()) { $Domain = NULL; $Rating = NULL; $stmt->bind_result($Domain, $Rating); while($stmt->fetch()) { array_push($arr, array("domain" => $Domain, "rating" => $Rating)); } } $db->close(); return $arr; } } } function SitesSort(& $Sites, & $Ratings) { $Positive = array(); $Negative = array(); $Zero = array(); for($i = 0; $i < count($Ratings); $i++) { 19 for($j = 0; $j < count($Sites); $j++) { if($Sites[$j]["domain"]==$Ratings[$i]["domain"]) { $Sites[$j]["used"] = true; if($Ratings[$i]["rating"] > 0) { array_push($Positive, $Sites[$j]); } elseif($Ratings[$i]["rating"] == 0) { array_push($Zero, $Sites[$j]); } else { array_push($Negative, $Sites[$j]); } } } } for($j = 0; $j < count($Sites); $j++) { if(! $Sites[$j]["used"]) array_push($Zero, $Sites[$j]); } return array_merge($Positive, $Zero, $Negative); } ?> Метод AddUrlToSearch (сервер) public int AddUrlToSearch(String urlToAdd){ System.out.printf("Added new seed url: %s\n", urlToAdd); PrintWriter writer = null; try { writer = new PrintWriter(new FileOutputStream(configName, true)); } catch (FileNotFoundException e) { try { writer = new PrintWriter(new FileOutputStream(configName)); } catch (FileNotFoundException e1) { } } writer.println(urlToAdd); writer.close(); return 1; } Метод setConfigUrls (сервер) public void setConfigUrls() { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(configName)); } catch (FileNotFoundException e) { System.out.println("Exception raised while opening config : "); e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } String line; try { while ((line = reader.readLine()) != null) { addUrl("http://" + line); 20 } } catch (IOException e) { System.out.println("Exception raised while reading config : "); e.printStackTrace(); } } Rate_maker.php <?php if ($_SERVER["REQUEST_METHOD"]=="POST") { if(isset($_POST["domain"]) && isset($_POST["rate"])) { $Domain = trim($_POST["domain"]); $Rating = 1 * trim($_POST["rate"]); if ($db = mysqli_connect("localhost", "RobotUser", "123", "Sites","3306")) { $db->select_db("Sites"); $queryString = "call RatingProc(?,?)"; if($stmt = $db->prepare($queryString)) { $stmt->bind_param('si', $Domain, $Rating); $stmt->execute(); } $queryString = "select NeedToAdd(?)"; $stmt = $db->prepare($queryString); $stmt->bind_param("s", $Domain); $stmt->execute(); $Need = -1; //file_put_contents("need1.txt", $Need); $stmt->bind_result($Need); $stmt->fetch(); //file_put_contents("need2.txt", $Need); if($Need != 0) { $context = stream_context_create(array('http' => array( 'method' => "POST", 'header' => "Content-Type: text/xml", 'content' => CreateXMLRPC("RobotLauncher.AddUrlToSearch", $Domain)))); $file = file_get_contents("http://192.168.56.1:4444/xmlrpc", false, $context); } $stmt->close(); $db->close(); } } } function CreateXMLRPC($ClassName, $SearchWord) { $request = new SimpleXMLElement("<methodCall/>"); $request->addChild("methodName",$ClassName); $params = $request->addChild("params"); $param = $params->addChild("param"); $value = $param->addChild("value"); $value->addChild("string",$SearchWord); return $request->asXML(); } 21 ?> RatingProc - Routine DELIMITER $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `RatingProc`(IN P_Domain VARCHAR(200), IN P_Rating INT) BEGIN declare L_HasDomain INT; declare L_ID INT; select count(*), max(ID) into L_HasDomain, L_ID from SitesRating where Domain = P_Domain; if(L_HasDomain = 0) then insert into SitesRating(Domain, Rating) values(P_Domain, P_Rating); else update SitesRating set Rating = Rating + P_Rating where L_ID = ID; end if; END NeedToAdd – Routine. DELIMITER $$ CREATE DEFINER=`root`@`localhost` FUNCTION `NeedToAdd`(p_domain VARCHAR(200)) RETURNS int(11) BEGIN 22 declare l_rating INT(11); declare l_added tinyint; select Rating, IsAdded into l_rating, l_added from SitesRating where Domain = p_domain; if(l_rating > 50 and l_added is null) then update SitesRating set IsAdded = 1 where Domain = p_domain; return 1; end if; RETURN 0; END 23 Приложение В Результаты работы программы 24 Таблица SitesRating 25