Моделирование инструкций позиционированного обновления и удаления
Если источник данных не поддерживает позиционированные инструкции обновления и удаления, драйвер может имитировать их. Например, библиотека курсоров 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 и добавляет его в список выбора. и удаляет предложение 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 и Телефон в этом предложении к переменным в своем кэше:
UPDATE Customers SET Address = ?, Phone = ?
WHERE (Name = ?) AND (Address = ?) AND (Phone = ?)