Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Если источник данных не поддерживает позиционированные инструкции обновления и удаления, драйвер может имитировать их. Например, библиотека курсоров ODBC эмулирует позиционные инструкции обновления и удаления. Общая стратегия имитации позиционированных инструкций обновления и удаления заключается в преобразовании позиционированных инструкций в поисковые. Это достигается заменой предложения WHERE CURRENT OF на предложение WHERE , которое идентифицирует текущую строку.
Например, поскольку столбец CustID однозначно идентифицирует каждую строку в таблице Customers, используется позиционированная инструкция удаления.
DELETE FROM Customers WHERE CURRENT OF CustCursor
может быть преобразовано в
DELETE FROM Customers WHERE (CustID = ?)
Драйвер может использовать один из следующих идентификаторов строк в предложении WHERE :
Столбцы, значения которых служат для уникальной идентификации каждой строки в таблице. Например, вызов SQLSpecialColumns с SQL_BEST_ROWID возвращает оптимальный столбец или набор столбцов, которые служат этой цели.
Псевдоколонки, предоставляемые некоторыми источниками данных, используются для уникальной идентификации каждой строки. Они также могут быть извлечены путем вызова SQLSpecialColumns.
Уникальный индекс, если он доступен.
Все столбцы в результирующем наборе.
То, какие именно столбцы должен использовать драйвер в создаваемом им предложении WHERE, зависит от самого драйвера. В некоторых источниках данных определение идентификатора строки может быть дорогостоящим. Тем не менее, выполняется быстрее и гарантируется, что имитированная инструкция обновляет или удаляет не более одной строки. В зависимости от возможностей базовых СУБД, использование идентификатора строки может быть дорогостоящим для настройки. Однако он быстрее выполняется и гарантирует, что имитируемая инструкция обновит или удалит только одну строку. Вариант использования всех столбцов в результирующем наборе обычно гораздо проще настроить. Однако выполнение выполняется медленнее, и если столбцы не однозначно идентифицируют строку, это может привести к непреднамеренно обновляемым или удаленным строкам, особенно если список выбора для результирующего набора не содержит все столбцы, существующие в базовой таблице.
В зависимости от того, какие из предыдущих стратегий поддерживает драйвер, приложение может выбрать стратегию, которую он хочет использовать с атрибутом оператора SQL_ATTR_SIMULATE_CURSOR. Хотя это может показаться странным для приложения, что ставит под угрозу непреднамеренное обновление или удаление строки, приложение может устранить этот риск, гарантируя, что столбцы в результирующем наборе однозначно определяют каждую строку. Это избавляет водителя от необходимости делать это.
Если драйвер выбирает использование идентификатора строки, он перехватывает инструкцию SELECT FOR UPDATE , которая создает результирующий набор. Если столбцы в списке выбора не определяют строку, драйвер добавляет необходимые столбцы в конец списка выбора. Некоторые источники данных имеют один столбец, который всегда однозначно определяет строку, например столбец ROWID в Oracle; Если такой столбец доступен, драйвер использует это. В противном случае драйвер вызывает SQLSpecialColumns для каждой таблицы в предложении FROM , чтобы получить список столбцов, однозначно определяющих каждую строку. Общее ограничение, которое приводит к этому методу, заключается в том, что моделирование курсоров завершается ошибкой, если в предложении FROM существует несколько таблиц.
Независимо от того, как драйвер определяет строки, обычно удаляет предложение FOR UPDATE OF от инструкции SELECT FOR UPDATE перед отправкой в источник данных. Предложение FOR UPDATE OF используется только с позиционированными инструкциями обновления и удаления. Источники данных, которые не поддерживают позиционированные инструкции обновления и удаления, обычно не поддерживают его.
Когда приложение отправляет позиционированную инструкцию обновления или удаления для выполнения, драйвер заменяет предложение WHERE CURRENT OF предложением WHERE , содержащим идентификатор строки. Значения этих столбцов извлекаются из кэша, поддерживаемого драйвером для каждого столбца, который он использует в предложении WHERE . После замены предложения WHERE драйвер отправляет инструкцию в источник данных для выполнения.
Например, предположим, что приложение отправляет следующую инструкцию, чтобы создать результирующий набор:
SELECT Name, Address, Phone FROM Customers FOR UPDATE OF Phone, Address
Если приложение установило SQL_ATTR_SIMULATE_CURSOR, чтобы запросить гарантию уникальности идентификаторов, и если источник данных не предоставляет псевдоколонок, которые всегда однозначно идентифицируют строку, драйвер вызывает SQLSpecialColumns для таблицы Customers, обнаруживает, что CustID является ключом к таблице Customers и добавляет его в список SELECT, удаляя предложение FOR UPDATE OF:
SELECT Name, Address, Phone, CustID FROM Customers
Если приложение не запрашивает гарантию уникальности, драйвер удаляет только предложение FOR UPDATE OF :
SELECT Name, Address, Phone FROM Customers
Предположим, что приложение прокручивает результирующий набор и отправляет следующий позиционированный запрос обновления для выполнения, где Cust — это имя курсора над результирующим набором.
UPDATE Customers SET Address = ?, Phone = ? WHERE CURRENT OF Cust
Если приложение не запрашивает гарантию уникальности, драйвер заменяет предложение WHERE и привязывает параметр CustID к переменной в своем кэше:
UPDATE Customers SET Address = ?, Phone = ? WHERE (CustID = ?)
Если приложение не запрашивает гарантию уникальности, драйвер заменяет предложение WHERE и привязывает параметры Name, Address и Phone в этом предложении к переменным в кэше:
UPDATE Customers SET Address = ?, Phone = ?
WHERE (Name = ?) AND (Address = ?) AND (Phone = ?)