Для чего нужен курсор
Курсор
Курсо́р (англ. cursor — указатель, стрелка прибора) — экранная пометка, показывающая:
Содержание
Текстовый курсор
Текстовый курсор применяется в интерфейсе командной строки и/или областях редактирования текста, показывая место, куда будет вставлен следующий символ (например, символ, набранный с клавиатуры), или место текста, в котором происходит редактирование в настоящий момент. На самом деле называется кареткой.
В большинстве командных оболочек для перемещения курсора по экрану (или тексту), применяются клавиши управления курсором — клавиши со стрелками в четырёх направлениях, а также клавиши Home и End для перемещения в логические начало и конец (строки), PageUp и PageDown для перемещения на логическую страницу вверх (назад) и вниз (вперед) и др. Однако, в отдельных программах, например, редакторе vi, перемещение курсора производится клавишами, отличными от курсорных.
Кроме перемещения текстового курсора, курсорные клавиши также часто используются для переключения между элементами, перемещения всевозможных выделений и подсветок (выделение участка текста цветом фона или его обрамление). Из-за этого подсветки иногда называют курсорами или псевдокурсорами.
Внешний вид курсора может зависеть от режима работы (текстовый или графический), применяемой программы и текущих режимов редактирования.
Текстовый режим
В текстовом режиме (или его эмуляции) курсор имеет вид горизонтальной чёрточки под знакоместом, или прямоугольника покрывающего все знакоместо (инвертирующего отображение символа или закрывающего его). Для удобства, курсор обычно выделяется мерцанием, яркостью или цветом.
Видом курсора программа может обозначать режим редактирования, так в текстовых редакторах i386 подстрочный курсор, как правило, означает режим вставки, а курсор на всё знакоместо — режим замены.
Текстовый курсор часто реализуется аппаратной схемой видеоадаптера, иногда в этом случае курсор отображается принудительно, и для того чтобы убрать его с экрана, ему присваивают позицию за пределами экрана.
Программы также могут создавать курсор самостоятельно (программно), атрибутами знакоместа — цветом символа и фона (например, инверсией — обменом их значениями), подчёркиванием и т. п.
Графический режим
В графическом режиме, за исключением случаев эмуляции текстового режима, из-за применения пропорциональных шрифтов (то есть, шрифтов с разной шириной символов) курсор отображается вертикальной чёрточкой (или символом вставки) между буквами. Как правило он мигает для удобства его нахождения (зрительный анализатор человека находит подвижные объекты быстрее), но может и не мигать.
Указатель
Указатель (иногда, в частном случае — курсор мыши) — (обычно отображается в виде стрелки) перемещается по экрану, повторяя движения мыши или другого указательного манипулятора (например джойстика или пера графического планшета). Нажатие кнопок и другие действия мыши применяются к текущему положению указателя. Например:
Внешний вид указателя обычно меняется в зависимости от:
В текстовом режиме курсор мыши, как правило, отображается изменёнными атрибутами знакоместа (например сменой цветов фона и символа на дополнительные). Некоторые программы способны отображать графический курсор в текстовом режиме динамическим изменением фонта в видеоадаптере.
Задание формы курсора при навигации по HTML-документу посредством CSS
Форму курсора при навигации по HTML-документу можно задать посредством свойства cursor каскадных таблиц стилей CSS.
Синтаксис применения этого свойства: [1]
cursor: [url(‘путь к курсору’),] | [ auto | crosshair | default | e-resize | help | move | n-resize | ne-resize | nw-resize | pointer | progress | s-resize | se-resize | sw-resize | text | w-resize | wait | inherit ]
SQL-Ex blog
Новости сайта «Упражнения SQL», статьи и переводы
Работа с курсорами SQL
В языке SQL курсоры служат указателями, которые позволяют языку написания приложений обрабатывать результаты запросов построчно. В данной статье вкратце объясняется концепция и показывается, как объявить курсор, открыть, извлечь из него данные, а затем закрыть.
Курсоры SQL
Данные в реляционной базе данных рассматриваются как множества. Как следствие, результаты запроса возвращаются операторами SELECT в виде результирующих наборов. Эти результирующие наборы есть не что иное, как одна или более строк и столбцов, извлеченных из одной или более таблиц. Вы можете пролистать результирующие наборы, чтобы вытащить необходимую вам информацию. Возвращаемые элементы данных используются языками программирования типа Java или любыми другими в конкретных целях приложения. Однако здесь имеется проблема, обусловленная несоответствием структур модели базы данных и моделью языка программирования.
Таким образом, курсор служит указателем, который позволяет языку программирования обрабатывать результаты запроса по одной записи за раз. Курсор может перемещаться по всем строкам результата запроса, позиционируясь всякий раз на отдельной строке. Рассмотрим следующий запрос SQL:
Вышеприведенный оператор вернет информацию о тех сотрудниках, чей день рождения попадает на текущие день и месяц. Результат может содержать много строк, но базовый язык приложения может обработать одновременно только одну строку. В результате, курсор объявляется как встроенный в соответствующий язык программирования оператор SQL. Затем курсор открывается подобно файлу, и извлекается отдельная строка из результата запроса. Остальные строки извлекаются последовательно до тех пор, пока курсор не будет закрыт.
Объявление курсора
Курсоры объявляются во многом подобно переменной. Курсору дается имя, имеются операторы для открытия курсора, извлечения результатов запроса и, наконец, закрытия курсора. Отметим, что различные реализации SQL поддерживают использование курсоров по-разному. Но здесь имеется общее соглашение как должен записываться курсор.
Мы должны использовать несколько операторов SQL для полной реализации функциональности курсора, т.к. одно лишь объявление курсора недостаточно для извлечения данных из базы данных. Вот 4 основных шага для работы с курсором:
DECLARE CURSOR: Объявление начинается с задания имени курсору и присвоения ему выражения запроса, которое будет вызываться при открытии курсора.
OPEN: Оператор open выполняет выражение запроса курсора и подготавливает результат запроса для последующего обхода (FETCH).
FETCH: Извлекает значения данных в переменные, которые затем могут передаваться базовому языку программирования или другим встроенным операторам SQL.
CLOSE: Курсор закрывается, и больше не может извлекать результаты запроса.
Основной частью объявления курсора является:
Необязательная часть, такая как [SENSITIVE | INSENSITIVE | ASENSITIVE] определяет, будет ли курсор чувствителен к изменениям, и будет ли отражать эти изменения в результатах запроса. SENSITIVE означает, что курсор реагирует на изменения, INSENSITIVE означает, что на курсор изменения не влияют, а ASENSITIVE означает, что изменения могут быть видны или не видны в курсоре. Если не указано, то предполагается опция ASENSITIVE.
Необязательные [SCROLL | NOSCROLL] определяют возможность пролистывания курсора. Если не указано, предполагается опция NOSCROLL.
Необязательные [ WITH HOLD | WITHOUT HOLD] определяют, сохранять ли курсор или автоматически закрывать его, когда связанная с курсором транзакция фиксируется. Если не указано, поддерживается опция WITHOUT HOLD.
Необязательные [ WITH RETURN | WITHOUT RETURN] определяют, следует ли возвращать результирующий набор курсора вызывающей стороне, такой как другая подпрограмма SQL или базовый язык. Если не указано, предполагается WITHOUT RETURN.
Предложение ORDER BY используется для сортировки возвращаемых результатов запроса.
Опция UPDATE относится к использованию операторов UPDATE или DELETE, связанных со строками, возвращаемыми оператором SELECT в определении курсора. Любая подобная модификация невозможна, если мы указываем опцию READ ONLY. Если не указана, то по умолчанию принимается опция UPDATE.
Итак, простой курсор может быть объявлен следующим образом:
Курсоры в MySQL
В MySQL имеется два основных типа курсоров: только на чтение (read-only) и только вперед (forward-only). Эти курсоры могут использоваться в хранимых процедурах MySQL. Они помогают нам итерационно обходить результаты запроса по одной строке за раз и извлекать значения в переменные для последующей обработки. Имеется возможность объявлять более одного курсора и вкладывать их в циклы. Заметим, что курсоры являются курсорами только на чтение, поскольку они для итераций используют временные таблицы. Обычно курсор выполняет запрос при его открытии.
Одной из проблем, связанных с курсорами в MySQL, является их отрицательное влияние на производительность из-за дополнительных операций ввода/вывода, которые они производят. Это особенно справедливо для больших типов данных, таких как BLOB и TEXT. Т.к. курсоры работают с временными таблицами, эти типы не поддерживаются в таблицах в памяти (in-memory). Следовательно, при работе с этими типами данных MySQL должна создавать временные таблицы на диске, что требует множества операций ввода/вывода, что особенно плохо для таких медленных устройств, которыми являются диски. Это основная причина низкой производительности курсоров.
MySQL также не поддерживает курсоров на стороне клиента, однако клиентское API может эмулировать их при необходимости. Но тогда это не сильно отличается от извлечения результата в массив на языке программирования типа Java, и манипулирования этим массивом вместо использования курсора.
Вот пример написания курсора в MySQL:
Вызвать хранимую процедуру можно так:
Процедура извлекает те строки из таблицы с именем employee, для которых дата рождения совпадает с текущим днем и месяцем, в курсор с именем mycursor и просто печатает их с помощью оператора SELECT.
Заключение
Обратные ссылки
Нет обратных ссылок
Комментарии
Показывать комментарии Как список | Древовидной структурой
Курсоры в Mysql.
)ENGINE=InnoDB
AUTO_INCREMENT=11 CHARACTER SET ‘utf8’ COLLATE ‘utf8_bin’
Допустим нам нужно получать по очереди каждый банк и производить с ним какие то действия, помочь в этом нам мог бы такой вот запрос
Select `bank`.* FROM `bank` LIMIT НОМЕР_НУЖНОЙ_НАМ_ЗАПИСИ,1
Поясним теперь подробнее. Сначала HANDLER, он нужен для обработки исключения — что делать когда данные закончатся ( то есть курсор будет пустым ). Таким образом когда данные закончатся, не с генерируется сообщение об ошибке, а значение переменной done выставиться в 1, изначально done = 0; подробнее об SQLSTATE читаем тут — dev.mysql.com/doc/refman/5.1/en/error-messages-server.html;
Error: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA)
Message: No data — zero rows fetched, selected, or processed
SQLSTATE: 02000 срабатывает когда достигнут конец курсора, или когда select или update возвращяет пустую строку.
Следующей строкой мы объявили курсор DECLARE cursor_name CURSOR FOR select_statement;
Открываем курсор Open cursor_name;
Дальше пока не достигаем конец курсора (WHILE done = 0 DO ) извлекаем данные и обрабатываем их.
Перед выходом из хранимой процедуры необходимо курсор закрыть. Close cursor_name;
Вроде ничего сложного. Но с SQLSTATE ‘02000’ связанно много подводных камней.
WHILE done = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* извлечем для банка сумму любого из его вкладов */
Select (ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution where BankId = vBankId limit 1;
делаем какие то действия
END WHILE ;
WHILE done = 0 DO
FETCH BankCursor INTO vBankId,vBankName,vAddress,vPhone;
/* извлечем для банка сумму любого из его вкладов */
Select Сount(ContributeAmount) INTO vContributeAmountSUM FROM bankdistribution where BankId = vBankId limit 1;
/* проверим действительно ли есть вклады в этом банке */
if (vContributeAmountSUM > 0) then
/* извлечем для банка сумму любого из его вкладов */
Select ContributeAmount INTO vContributeAmountSUM FROM bankdistribution where BankId = vBankId limit 1;
end if ;
делаем какие то действия
END WHILE ;
первым запросом мы проверили а есть ли вклады (если их нет то vContributeAmountSUM == 0 ) и только если таковые имеются мы извлекаем данные.
теперь допустим нам нужно излечь общую сумму на счетах в разных банках у каждого клиента
Declare ClientSummCursor Cursor for Select sum
Declare ClientSummCursor Cursor for Select sum (`bankdistribution`.`ContributeAmount`),`bankdistribution`.`ClientId` FROM `bankdistribution` Inner Join client on (client.ClientId = bankdistribution.`ClientId`) where 1 group by `bankdistribution`.`ClientId`;
может возникнуть та же ситуация, когда данные в курсоре ClientSummCursor, закончатся раньше чем данные в BankCursor, сработает SQLSTATE: 02000, переменная done установится в 1, и цикл while закончиться раньше чем мы ожидали. Этого можно избежать поступив следующим образом
Всем дочитавшим до этого места спасибо, надеюсь это статься покажется кому то полезной.
Что такое курсор?
Операции в реляционной базе данных выполняются над множеством строк. Набор строк, возвращаемый инструкцией SELECT, содержит все строки, которые удовлетворяют условиям, указанным в предложении WHERE инструкции. Такой полный набор строк, возвращаемых инструкцией, называется результирующим набором. Приложения, особенно интерактивные и интерактивные, не всегда эффективно работают с результирующим набором как единое целое. Им нужен механизм, позволяющий обрабатывать одну строку или небольшое их число за один раз. Курсоры являются расширением результирующих наборов, которые предоставляют такой механизм.
Курсор реализуется библиотекой курсоров. Библиотека курсоров — это программное обеспечение, которое часто реализуется как часть системы базы данных или API доступа к данным, которое используется для управления атрибутами данных, возвращаемых из источника данных (результирующий набор). Эти атрибуты включают управление параллелизмом, положение в результирующем наборе, число возвращаемых строк и возможность перемещения вперед или назад (или и то, и другое) с помощью результирующего набора (прокрутка).
Курсор отслеживает позицию в результирующем наборе и позволяет выполнять несколько операций по строкам в результирующем наборе с возвратом к исходной таблице или без него. Иными словами, курсоры основываются на концептуальном возврате результирующего набора на основе таблиц в базах данных. Курсор имеет имя, так как указывает текущую позицию в результирующем наборе, так же как курсор на экране компьютера указывает на текущую позицию.
Прежде чем перейти к изучению особенностей использования в ADO, важно ознакомиться с понятием курсоров.
С помощью курсоров можно выполнять следующие задачи:
Укажите положение в конкретных строках результирующего набора.
Получение одной строки или блока строк на основе текущего расположения результирующего набора.
Изменение данных в строках в текущей позиции результирующего набора.
Определите различные уровни чувствительности к изменениям данных, внесенным другими пользователями.
Например, рассмотрим приложение, которое отображает список доступных продуктов для потенциального покупателя. Покупатель прокручивает список, чтобы просмотреть сведения о продукте и стоимость, и, наконец, выбирает продукт для покупки. В оставшейся части списка появляется дополнительная прокрутка и выбор. С точки зрения покупателя продукты появятся по одному за раз, но приложение использует прокручиваемый курсор для просмотра результирующего набора.
Курсоры можно использовать различными способами:
С некоторыми или всеми строками в одной таблице.
С некоторыми или всеми строками из логически соединяемых таблиц.
Для чтения или обновления на уровне курсора или поля.
Как однопроходные или полностью прокручиваемые.
С набором ключей курсора, расположенным на сервере.
Конфиденциальные изменения базовой таблицы, вызванные другими приложениями (например, членство, сортировка, вставка, обновления и удаления).
Существующий на сервере или клиенте.
Курсоры только для чтения помогают пользователям просматривать результирующий набор, а курсоры чтения и записи могут реализовывать отдельные обновления строк. Сложные курсоры можно определять с помощью формируются, которые указывают на строки базовой таблицы. Хотя некоторые курсоры доступны только для чтения в прямом направлении, другие могут перемещаться назад и выполнять динамическое обновление результирующего набора на основе изменений, внесенных другими приложениями в базу данных.
Не все приложения должны использовать курсоры для доступа к данным и их обновления. Некоторые запросы просто не нуждаются в непосредственной обновлении строк с помощью курсора. Курсоры должны быть одним из последних методов, выбранных для получения данных, а затем следует выбирать наименьший возможный курсор. При создании результирующего набора с помощью хранимой процедуры результирующий набор не обновляется с помощью методов изменения или обновления курсора.
Параллелизм
В некоторых многопользовательских приложениях очень важно, чтобы данные, представляемые конечному пользователю, были как можно более актуальными. Классическим примером такой системы является система резервирования авиакомпании, где многие пользователи могут полагаться на одно и то же место на данном полете (и, следовательно, в одну запись). В таком случае проект приложения должен выполнять параллельные операции над одной записью.
В других приложениях параллелизм не так важен. В таких случаях затраты, связанные с своевременным хранением данных, не могут быть выровнены по ширине.
Положение
Курсор также отслеживает текущую позицию в результирующем наборе. Можно рассматривать положение курсора как указатель на текущую запись, аналогично тому, как индекс массива указывает на значение в определенном месте в массиве.
Прокручиваемость
Тип курсора, используемый приложением, также влияет на возможность перемещения по строкам в результирующем наборе вперед и назад. Иногда это называется прокруткой. Возможность перемещаться вперед и назад по результирующему набору увеличивает сложность курсора и поэтому реализуется более затратно. По этой причине следует запрашивать курсор с этой функцией только при необходимости.