Компилятор, совместимый с языками семейства xBase и Clipper | ||
---|---|---|
Пред. | Глава 13. Работа с SQL серверами | След. |
SQLList() --> aAvailableDrivers
Двухмерный массив с описаниями доступных драйверов, по одной строке на драйвер. Первый столбец содержит краткую строку - идентификатор драйвера; второй - имя СУБД с которой работает драйвер; третий - описание драйвера.
SQLList() используется для получения списка доступных приложению драйверов для доступа к SQL серверам. Драйвер доступен, когда приложение слинковано с соответствующей библиотекой. Если ни один драйвер не прилинкован возвращается пустой массив.
Первый элемент строки возвращаемого массива содержит строку-идентификатор (ID) СУБД, с которым работает драйвер, используемый в качестве значения параметра <cRDBMS> конструктора класса TConnect ConnectNew().
$cat test.prg // test.prg procedure Main() ? SQLList()[1] ? SQLList()[2] return NIL $clip -e test.prg -lclip-mysql -lclip-postgres $./test {MS, MySQL, Generic MySQL for CLIP driver, v.1.0}, {PG, PostgreSQL, Generic PostgreSQL for CLIP driver v.1.0}
ConnectNew(<cRDBMS>,[<RDBMS specific>,...],[<cCharset>],[<cIsolation>]) --> TConnect object
идентификатор СУБД; см. информацию о специфике использования конкретной СУБД
несколько специфичных для используемой СУБД параметров; см. информацию о специфике использования конкретной СУБД
(9-й параметр) кодировка, используемая сервером
(10-й параметр) уровень изоляции по умолчанию; см. информацию о специфике использования конкретной СУБД
Объект класса TConnect.
ConnectNew() подключается к серверу, создает и возвращает объект класса TConnect. Этот объект может использоваться для старта/завершения транзакций, выполнения операторов SQL и для получения наборов записей - результата оператора SELECT.
Дополнительный параметр <cCharset> используется в случаях, когда кодировки сервера и клиента не совпадают. Все перекодировки строк, получаемых с сервера и передаваемых обратно производятся автоматически. Если этот параметр не передан используется SET("SQL_CHARSET"). Обратите внимание, что изменение SET("SQL_CHARSET") после подключения к серверу не имеет эффекта для этого подключения.
Если дополнительный параметр <cIsolation> не передан, используется соответствующая переменная SET, например SET("OR_ISOLATION_LEVEL") для Oracle. Если такой переменной SET нет, используется SET("SQL_ISOLATION_LEVEL").
![]() | Вместо уровня изоляции по умолчанию может быть использоваться другой, определяемый соответствующим параметром функции TConnect:Start(). Изменение значения соответствующей переменной SET после того как подключение произведено не влияет на умалчиваемый уровень изоляции этого подключения. |
Когда приложению больше не требуется SQL сервер, оно должно отключиться от сервера и освободить занимаемые подключением ресурсы при помощи вызова функции-деструктора TConnect:Destroy().
В этом примере производится подключение к локальному серверу PostgreSQL.
conn := ConnectNew("PG",,,,,"template1") ... conn:Destroy()
Ниже перечислены конструктор и методы класса TConnect:
ConnectNew() | Конструктор TConnect |
TConnect:Command() | выполнение оператора SQL |
TConnect:Commit() | завершение успешной транзакции |
TConnect:Destroy() | отключение от сервера и деструктор TConnect |
TConnect:CreateRowset() | Конструктор TRowset |
TConnect:Rollback() | откат транзакции |
TConnect:Start() | старт транзакции |
Command(<cSQL>,[<aParameters>]) --> nAffectedRows
строка содержащая оператор SQL для выполнения
двухмерный массив с параметрами SQL, по одной строке на параметр. Каждая строка должна содержать как минимум два элемента. В первом - имя параметра, во втором - его значение. Третий элемент используется только с Oracle (обязателен), и содержит числовое значение - идентификатор типа данных Oracle. Дополнительный четвертый элемент служит для индикации бинарного значения; если .T. перекодировки не производятся
Количество затронутых записей.
Command() используется для выполнения операторов SQL,кроме запросов SELECT (в т.ч. операторов, возвращающих результирующие строки). Для выполнения запроса, возвращающего строки, используйте TConnect:CreateRowset() даже если вы не заинтересованы в получении результатов.
Оператор SQL может получать параметры. Имени параметра в <cSQL> должен предшествовать символ ':'. Значения параметров передаются в двухмерном массиве <aParameters>.
Если нет активной транзакции, изменения, сделанные оператором <cSQL> коммитятся (вступают в силу) сразу. Если нужно другое поведение вызывайте TConnect:Start() явно.
Возвращаемое значение - количество затронутых записей, например количество удаленных записей в случае оператора DELETE.
conn:Command("CREATE TABLE mytable (fname char(20),lname char(20))") conn:Command("INSERT INTO mytable VALUES (:firstname,:lastname)",; {{"firstname","John"},{"lastname","Smith"}}) ? conn:Command("DELETE FROM mytable WHERE fname=:fname",; {{"fname","John"}}) // 1
Commit() --> NIL
Commit() подтверждает все изменения, сделанные в транзакции, запущенной функцией TConnect:Start(),и завершает транзакцию. Если нет активных транзакций, генерируется ошибка.
conn:Start() // ... // some changes // ... conn:Commit()
Destroy() --> NIL
Когда приложению больше не требуется доступ к SQLсерверу, следует отсоединитьсяот него и освободить занимавшиеся системные ресурсы при помощи вызова деструктора Destroy().
conn := ConnectNew("PG",,,,,"template1") // ... // do some work // ... conn:Destroy()
CreateRowset(; <cSelectSQL>,; [<aParameters>],; [<cInsertSQL>],; [<cDeleteSQL>],; [<cUpdateSQL>],; [<cRefreshSQL>],; [<cIdName>],; [<aOrders>],; [<cGenIdSQL>],; [<lNoFetch>],; [<bEval>],; [<nEvery>]; ) --> TRowset object
строка содержащая SQL запрос, который следует выполнить
двухмерный массив с параметрами SQL, по одной строке на параметр. Каждая строка должна содержать как минимум два элемента. В первом - имя параметра, во втором - его значение. Третий элемент используется только с Oracle (обязателен), и содержит числовое значение - идентификатор типа данных Oracle. Дополнительный четвертый элемент служит для индикации бинарного значения; если .T. перекодировки не производятся. Переданные параметры могут использоваться в SQL операторах, описываемых ниже
оператор SQL, который следует выполнить при добавлении новой строки к набору
оператор SQL, который следует выполнить при удалении строки из набора
оператор SQL, который следует выполнить при изменении строки набора
запрос SQL, который следует выполнить для обновления текущей строки набора
имя поля-идентификатора (только для Interbase, ODBC и DBTCP)
массив с определениями локальных индексов в виде серии подмассивов, по одному на индекс. Первый элемент подмассива определяет имя индекса, второй имя поля или блок кода возвращающий значения ключа. Третий элемент требуется только для символьных ключей и определяет длину ключа
оператор SQL для получения нового уникального значения поля-идентификатора, используемое в дальнейшем с оператором <cInsertSQL> (только для Interbase)
логическое значение определяющее режим загрузки записей. Если передано .F. все записи загружаются сразу, если .T. - записи загружаются позже (по требованию). По умолчанию - .F.
блок кода, выполняемый в процессе загрузки записей. Этот блок кода получает параметр - объект TRowset. Если блок кода возвращает .F. процесс загрузки прекращается досрочно. В режиме 'загрузка по требованию' (когда <lNoFetch> - .T.) этот параметр игнорируется
определяет количество загруженных записей между между выполнениями <bEval> (если передан). По умолчанию - 1, то есть <bEval> выполняется после каждой загруженной записи
CreateRowset() выполняет запрос SELECT, строит локальный набор результирующих записей и возвращает объект TRowset. То есть эту функцию можно рассматривать как конструктор класса TRowset. 'Запрос SELECT' означает любой оператор SQL, возвращающий результирующие записи (или пустой набор записей). Использование оператора SQL любого другого вида приведет к ошибке.
<cInsertSQL>, <cDeleteSQL>, <cUpdateSQL> - дополнительные параметры, предназначенные для облегчения модификации таблиц базы данных. Если не переданы, соответствующие изменения набора записей не отражаются в базе данных. <cInsertSQL> выполняется автоматически методом TRowset:Append(). Таким же образом, <cDeleteSQL> выполняется методом TRowset:Delete(), а <cUpdateSQL> - методом TRowset:Write().
<cRefreshSQL> выполняется автоматически методом TRowset:RefreshCurrent(). <cRefreshSQL> должен запрашивать точно такой же список полей, что и <cSelectSQL>.
Редактируемый набор записей должен содержать поле - идентификатор записи с уникальными значениями, используемый для связывания записей таблицы базы данных и строк набора. Необходимо явно включать это поле в список запрашиваемых полей запроса SELECT. Для различных СУБД существуют различные подходы к реализации механизма связывания записей таблицы и строк набора.
Некоторые СУБД имеют 'скрытые' поля - идентификаторы записей для каждой хранимой таблицы (ROWID в Oracle, OID в PostgreSQL). Эти поля создаются неявно, даже если вы не включали его описания в список полей оператора CREATE TABLE. PostgreSQL понимает такой синтаксис:
SELECT oid,* FROM mytable
В отличие от PostgreSQL, Oracle не понимает такого синтаксиса. Необходимо перечислить все запрашиваемые поля:
SELECT rowid,fname,lname FROM mytable
Некоторые СУБД предоставляют возможность использования автоинкрементных полей с уникальными значениями. Синтаксис оператора CREATE TABLE вMySQL позволяет использовать предложение AUTO_INCREMENT в определении поля. CLIP распознает такие поля и использует их в качестве идентификаторов записей. Никаких других действий кроме включения поля AUTO_INCREMENT в таблицу, которую предполагается редактировать при помощи методов класса TRowset, не требуется.
Некоторые СУБД (Interbase) предоставляют механизм триггеров и генераторы уникальных значений. Типичный подход в этом случае - создать триггер BEFORE INSERT, который получает уникальное значение от генератора и присваивает его полю - идентификатору записи. Но не существует способа определить значение поля - идентификатора записи вновь вставленной записи. То есть невозможно изменить или удалить (при помощи операторов UPDATE и DELETE) вновь вставленную запись (добавленную после того как был создан объект TRowset). Есть два выбора:
оформлять приложение с учетом этого ограничения (никогда не изменять вновь вставленные записи);
не использовать триггер BEFORE INSERT, а передавать конструктору TRowset параметр <cGenIdSQL> с запросом к генератору уникальных значений. Этот оператор должен возвращать новое уникальное значение, которое будет затем присвоено полю с именем <cIdName> во время выполнения оператора <cInsertSQL>.
![]() | Атрибут таблиц Interbase под названием RDB$DB_KEY в действительности не является идентификатором записи, а скорее адресом записи, которое может меняться (как RECNO(), значение которого может измениться после PACK). Поэтому этот атрибут не используется в качестве идентификатора записей. |
В случае использования СУБД не предоставляющих никаких из вышеперечисленных возможностей (ODBC,DBTCP), необходимо передавать параметр <cIdName> с именем поля - идентификатора записи и оформлять ваши приложения таким образом, чтобы никогда не изменялись вновь вставленные записи.
Операторы SQL <cInsertSQL>, <cDeleteSQL>, <cUpdateSQL> и <cRefreshSQL> получают значения полей через параметры SQL с именами совпадающими с именами полей набора. Например:
<cSelectSQL> - SELECT DriverID AS id,fname,lname FROM mytable <cInsertSQL> - INSERT INTO mytable (fname,lname) VALUES (:fname,:lname) <cUpdateSQL> - UPDATE mytable SET fname=:fname,lname=:lname WHERE DriverId=:id <cDeleteSQL> - DELETE FROM mytable WHERE DriverId=:id <cRefreshSQL> - SELECT DriverID,fname,lname FROM mytable WHERE DriverId=:id
Имеется три макроса: %FIELDS, %VALUES для использования в операторе INSERT; %LIST для использования в операторе UPDATE. %FIELDS преобразуется в список имен полей; %VALUES - в список параметров; %LIST - в список полей и параметров. Например:
INSERT INTO mytable (%FIELDS) VALUES (%VALUES) UPDATE mytable SET %LIST
Имеется два режима загрузки записей, управляемые параметром <lNoFetch>: полная загрузка и загрузка по требованию.
В первом режиме (<lNoFetch>==.F.) все результирующие записи загружаются до завершения CreateRowset(). В этом режиме можно сразу использовать TRowset:Lastrec() для определения количества результирующих записей. Можно использовать <bEval> для наблюдения и прерывания процесса загрузки.
Во втором режиме (<lNoFetch>==.T.) записи загружаются по требованию (в процессе навигации по набору). Этот режим гораздо быстрее, но Lastrec() возвращает рельное количество результирующих записей только после того как загрузятся все записи. В этом режиме параметр <bEval> игнорируется.
Когда приложению больше не требуется набор строк, оно должно освободить занимаемые ресурсы при помощи вызова метода-деструктора TRowset:Destroy().
Простой пример, в котором создается нередактируемый набор записей:
rs := conn:CreateRowset("SELECT * FROM mytable WHERE fname = 'John'") rs:Browse()
Создание набора записей с использованием параметров SQL:
rs := conn:CreateRowset("SELECT * FROM mytable WHERE fname = :par1",; {{"par1","John"}}) rs:Browse()
Создание редактируемого набора записей:
rs := conn:CreateRowset("SELECT id,fname,lname FROM mytable",NIL,; "INSERT INTO mytable (%FIELDS) VALUES (%VALUES)",; "DELETE FROM mytable WHERE id=:id",; "UPDATE mytable SET fname=:fname,lname=:lname",; "SELECT id,fname,lname FROM mytable WHERE id=:id",; "id")
Создание набора записей с локальными индексами 'id' и 'fullname':
rs := conn:CreateRowset("SELECT id,fname,lname FROM mytable",,,,,,,; {{"id","id"},; {"fullname",{|rs| rs:GetValue("fname")+rs:GetValue("lname")},40}}) rs:Browse() // show rows in natural order rs:SetOrder("id") rs:Browse() // show rows ordered by id rs:SetOrder("fullname") rs:Browse() // show rows ordered by fname and lname
Использование <bEval> для наблюдения за процессом загрузки (через каждые 100 загруженные записи печатается точка), который можно прервать нажатием ESC:
rs := conn:CreateRowset("SELECT * FROM hugetable",,,,,,,,,,; {|| qqout("."),inkey() != K_ESC}, 100) rs:browse()
Загрузка записей по требованию:
rs := conn:CreateRowset("SELECT * FROM hugetable",,,,,,,,,.T.) rs:Gotop() ? rs:Fetched() // 1 ? rs:Lastrec() // 0 for i:=1 to 100 rs:Skip() ? rs:Fetched() // 2,3,...,101 next rs:FetchAll() ? rs:Lastrec() == rs:Fetched() // .T.
Rollback() --> NIL
Rollback() отменяет все изменения сделанные во время транзакции и завершает транзакцию. Если нет активной транзакции генерируется ошибка.
conn:Start() // ... // some changes // ... conn:Rollback()
Start([<cIsolation>],[<cLockTables>]) --> NIL
Start() стартует новую транзакцию. В момент запуска новой транзакция предыдущая должна быть завершена, иначе генерируется ошибка. Транзакция должна быть когда-нибудь завершена при помощи TConnect:Commit() или TConnect:Rollback().
Если нет активной транзакции, все изменения таблицы вступают в силу после каждого выполненного оператора SQL.
conn:Start() // ... // some changes // ... conn:Commit() // commit changes
Ниже перечислены конструктор и методы класса TRowset:
TConnect:CreateRowset() | Конструктор TRowset |
TRowset:Append() | добавление новой строки в набор |
TRowset:Bof() | определение достижения начала набора |
TRowset:Browse() | просмотр набора строк в окне |
TRowset:CreateOrder() | создание нового локального индекса |
TRowset:Delete() | удаление строки из набора |
TRowset:Destroy() | уничтожение объекта TRowset |
TRowset:Eof() | определение достижения конца набора |
TRowset:FetchAll() | дозагрузка оставшихся записей |
TRowset:Fetched() | определение количества загруженных строк |
TRowset:FieldBinary() | определение, является ли поле бинарным |
TRowset:FieldBlock() | создание блока кода для доступа к заданному полю набора |
TRowset:FieldDec() | определение количества знаков после запятой для заданного поля |
TRowset:FieldLen() | определение длины заданного поля |
TRowset:FieldName() | определение имени поля по заданной позиции |
TRowset:FieldNo() | определение позиции поля с заданным именем |
TRowset:FieldNullable() | определение, может ли поле принимать значения NULL |
TRowset:FieldType() | определение типа данных поля |
TRowset:FieldTypeSQL() | определение типа данных поля (в терминах используемой СУБД) |
TRowset:FieldUnsigned() | определение, является ли поле беззнаковым |
TRowset:GetValue() | получение значения поля в текущей строке |
TRowset:GoBottom() | перемещение к последней логической строке |
TRowset:Goto() | перемещение к заданной строке |
TRowset:GoTop() | перемещение к первой логической строке |
TRowset:KeyNo() | определение логического номера текущей строки |
TRowset:Lastrec() | определение количества строк в наборе |
TRowset:NFields() | определение количества полей в наборе |
TRowset:Read() | чтение текущей строки |
TRowset:Recno() | определение номера текущей строки |
TRowset:RefreshAll() | обновление набора путем повторного выполнения запроса SELECT |
TRowset:RefreshCurrent() | обновление текущей строки путем выполнения <cRefreshSQL> |
TRowset:Seek() | поиск строки с заданным значением ключа |
TRowset:SetOrder() | установка логического порядка записей |
TRowset:SetValue() | присвоение значения полю текущей строки |
TRowset:Skip() | перемещение относительно текущей записи |
TRowset:Write() | запись текущей строки |
Append(<oRow>) --> NIL
объект со значениями полей
Append() добавляет новую строку к набору и присваивает значения атрибутов <oRow> соответствующим полям новой записи.
Если конструктору набора записей был передан параметр <cInsertSQL>, то последний исполняется на SQL сервере со значениями полей новой записи.
Если набор был создан в режиме 'загрузка по требованию' (<lNoFetch>==.T.), то предварительно дозагружаются все оставшиеся записи.
Append() увеличивает количество строк в наборе, возвращаемое методом TRowset:Lastrec().
Указатель перемещается на новую строку.
rs := conn:CreateRowset("SELECT id,fname,lname FROM mytable",,; "INSERT INTO mytable (fname,lname) VALUES (:fname,:lname)") obj := map() // create an empty object obj:fname := "John" // set attributes with the same names as fields obj:lname := "Smith" // ... // add new row and execute // INSERT INTO mytable (fname,lname) VALUES ('John','Smith') rs:Append(obj)
Bof() --> lBoundary
.T. после попытки переместиться в обратном направлении за первую логическую строку набора; в противном случае возвращается .F. Если набор не содержит ни одной строки возвращается .T.
Bof() используется для проверки условия достижения границ набора при перемещении указателя в обратном направлении при помощи метода TRowset:Skip().
После того, как функцией Bof() будет установлено значение .T., оно остается до тех пор, пока не будет сделана очередная попытка передвижения указателя записи.
TRowset:Skip() является единственной функцией, которая может установить значение Bof() == .T.
rs := conn:CreateRowset("SELECT * FROM mytable") ? rs:Recno() // 1 ? rs:Bof() // .F. rs:Skip(-1) ? rs:Recno() // 1 ? rs:Bof() // .T.
Browse([<nTop>],[<nLeft>],[<nBottom>],[<nRight>],; [<asColumns>],[<asHeaders>],[<anWidths>]) --> NIL
определяют координаты окна. По умолчанию 1, 0, MAXROW(), MAXCOL().
массив строк с именами полей, используемых в качестве значений колонок
параллельный массив строк содержащих заголовки для каждой колонки
параллельный массив содержащий размеры каждой колонки
Browse() - функция пользовательского интерфейса предоставляющая простой просмотр строк набора.
rs := conn:CreateRowset("SELECT id,fname,lname FROM mytable",,,,,,,,,.T.) rs:Browse(,,,,{"fname","lname"},{"First name","Last name"},{20,20})
CreateOrder(<cOrderName>,<cFieldName>|<bExpression>,[<nKeyLength>]) --> NIL
имя создаваемого индекса
имя поля, значения которого используются в качестве ключей
блок кода, используемый для вычисления ключей; он получает объект TRowset в качестве параметра
длина ключа; требуется только для символьных ключей
CreateOrder() используется для создания локального индекса, то есть индекса в памяти, управляющего логическим порядком строк в наборе. Созданный индекс может затем быть установлен управляющим при помощи метода TRowset:SetOrder(). Кроме того, управляющий индекс может использоваться для быстрого поиска строки, содержащей заданный ключ при помощи метода TRowset:Seek() function.
Если набор был создан в режиме 'загрузка по требованию' (<lNoFetch>==.T.), то предварительно дозагружаются все оставшиеся записи.
В этом примере создаются два индекса ('birthdate' и 'fullname'); показываются записи отсортированные в порядке даты рождения и полного имени; ищется работник, чье имя начинается с 'Joh':
rs := conn:CreateRowset("SELECT bdate,fname,lname FROM employee") rs:CreateOrder("birthdate","bdate") rs:CreateOrder("fullname",{|rs| rs:GetValue("fname")+rs:GetValue("lname")},40) rs:SetOrder("birthdate") rs:Browse() rs:SetOrder("fullname") rs:Browse() ? rs:Seek("Joh") // .T. row := rs:Read() ? row:fname // John
Delete() --> NIL
Delete() удаляет текущую строку из набора.
Если конструктору набора был передан параметр <cDeleteSQL>, последний выполняется на SQL сервере со значением поля - идентификатора текущей записи.
Если набор был создан в режиме 'загрузка по требованию' (<lNoFetch>==.T.), то предварительно дозагружаются все оставшиеся записи.
Delete() уменьшает количество строк в наборе, возвращаемое методом TRowset:Lastrec().
Если нет управляющего индекса позиция указателя текущей строки не изменяется, или перемещается к последней строке (когда удаляется последняя физическая строка (Recno()==Lastrec()).
Если есть управляющий индекс (установленный методом TRowset:SetOrder()) указатель текущей строки перемещается к следующей логической строке, или перемещается к последней логической строке (когда удаляется строка с наибольшим значением ключа).
Если удаляется последняя оставшаяся строка, состояния Bof() и Eof() устанавливаются в .T. и TRowset:Recno() возвращает 0.
rs := conn:CreateRowset("SELECT id,fname,lname FROM mytable",,,; "DELETE FROM mytable WHERE id=:id") ? rs:Lastrec() // 10 // delete a row and execute // DELETE FROM mytable WHERE id=... rs:Delete() ? rs:Lastrec() // 9
Destroy() --> NIL
Когда приложению больше не требуется набор строк, оно должно освободить занимаемые ресурсы при помощи вызова метода-деструктора TRowset:Destroy().
rs := conn:CreateRowset("SELECT * FROM mytable") // ... // do some work // ... rs:Destroy()
Eof() --> lBoundary
.T. после попытки переместиться в прямом направлении за последнюю логическую строку набора; в противном случае возвращается .F. Если набор не содержит ни одной строки возвращается .T.
Eof() используется для проверки условия достижения границ набора при перемещении указателя в прямом направлении при помощи метода TRowset:Skip().
После того, как функцией Eof() будет установлено значение .T., оно остается до тех пор, пока не будет сделана очередная попытка передвижения указателя записи.
TRowset:Skip() является единственной функцией, которая может установить значение Eof() == .T.
![]() | В отличие от команды SKIP, использеумой в XBase, TRowset:Skip() никогда не перемещает указатель за последнюю логическую строку. Когда TRowset:Eof() возвращает .T. указатель находится на последней логической строке, а не на Lastrec()+1. |
rs := conn:CreateRowset("SELECT * FROM mytable") rs:GoBottom() ? rs:Recno() // 100 ? rs:Eof() // .F. rs:Skip() ? rs:Recno() // 100 ? rs:Eof() // .T. rs:Skip(-1) ? rs:Recno() // 99 ? rs:Eof() // .F.
FetchAll() --> nLastrec
Количество строк в наборе.
FetchAll() дозагружает оставшиеся записи в набор. Это бывает необходимо, когда набор был создан в режиме 'загрузка по требованию'. Если все записи уже загружены, FetchAll() ничего не делает.
rs := conn:CreateRowset("SELECT * FROM mytable",,,,,,,,,.T.) ? rs:Lastrec() // 0 ? rs:Fetched() // 1 ? rs:FetchAll() // number of selected rows ? rs:Lastrec() // - " - ? rs:Fetched() // - " -
Fetched() --> nNumberOfFetchedRows
Количество загруженных строк.
Fetched() используется для определения количества загруженных строк. Это бывает необходимо в блоке кода <bEval>, передаваемом конструктору набора TConnect:CreateRowset(), и при создании набора в режиме 'загрузка по требованию'.
Выводится количество загруженных строк в процессе загрузки:
rs := conn:CreateRowset("SELECT * FROM hugetable",,,,,,,,,,; {|rs| qout(rs:Fetched())},100)
Использование Fetched() с набором, созданным в режиме 'загрузка по требованию':
rs := conn:CreateRowset("SELECT * FROM hugetable",,,,,,,,,.T.) ? rs:Fetched() // 1 rs:Skip() ? rs:Fetched() // 2 rs:Skip(100) ? rs:Fetched() // 102
FieldBinary(<nFieldNo> | <cFieldName>) --> lBinary
позиция поля в списке полей
имя поля
.T. если поле бинарное, .F. в противном случае.
FieldBinary() используется для определения, является ли поле бинарным. Бинарные поля не подвергаются перекодировкам.
? rs:FieldBinary("fname") // .F.
FieldBlock(<nFieldNo> | <cFieldName>) --> bBlock
позиция поля в списке полей
имя поля
Блок кода, устанавливающий или получающий значение поля.
FieldBlock() строит блок кода для доступа к заданному полю. Если блоку передается параметр, значение поля устанавливается значением этого параметра. Если блоку не передается параметров, то он возвращает значение поля.
![]() | Изменение набора с использованием этого блока кода не вызывает незамедлительного выполнения <cUpdateSQL> (параметра конструктора набора TConnect:CreateRowset()). Выполнение <cUpdateSQL> на сервере инициируется лишь методом Write(), а также всеми методами, перемещающими указатель (Gotop()Gobottom()Goto() и Skip()). |
cb := rs:FieldBlock("fname") ? eval(cb) // 'John' eval(cb,'Richard') ? eval(cb) // 'Richard' rs:Write(rs:Read()) // cause UPDATE-ing on the server
FieldDec(<nFieldNo> | <cFieldName>) --> nDec
позиция поля в списке полей
имя поля
Количество знаков после запятой для заданного поля.
FieldDec() используется для определения количества десятичных знаков после запятой, используемых в заданном поле.
? rs:FieldDec("salary")
FieldLen(<nFieldNo> | <cFieldName>) --> nDec
позиция поля в списке полей
имя поля
Длина поля (в терминах используемой СУБД).
FieldLen() используется для определения длины заданного поля, в терминах используемой СУБД. Например, длина поля типа 'FLOAT' равна 4.
? rs:FieldLen("salary")
FieldName(<nFieldNo>) --> cFieldName
позиция поля в списке полей
Имя поля.
FieldName() используется для определения имени поля с заданной позицией.
? rs:FieldName(1) // fname
FieldName(<cFieldName>) --> nFieldNo
имя поля
Позиция поля.
FieldNo() используется для определения позиции поля с заданным именем.
? rs:FieldName('fname') // 1
FieldNullable(<nFieldNo> | <cFieldName>) --> lNullable
позиция поля в списке полей
имя поля
.T. если поле может принимать значения NULL; .F. - в противном случае (поле NOT NULL).
FieldNullable() используется для определения, может ли поле принимать значения NULL.
? rs:FieldNullable("fname") // .T.
FieldType(<nFieldNo> | <cFieldName>) --> cType
позиция поля в списке полей
имя поля
Код, определяющий тип поля (XBase).
FieldType() используется для определения типа поля. Функция возвращает один символ, определяющий тип данных. Возвращается один из следующих символов:
C - строка символов
N - число
D - дата
T - дата и время
L - логическое значение
? rs:FieldType("salary") // 'N'
FieldTypeSQL(<nFieldNo> | <cFieldName>) --> nType
позиция поля в списке полей
имя поля
Код, определяющий тип поля (в терминах используемой СУБД).
FieldTypeSQL используется для определения типа поля, в терминах используемой СУБД. Типы данных конкретных СУБД определены в соответствующих заголовочных *.ch файлах, включенных в состав пакетов.
? rs:FieldTypeSQL("salary")
FieldUnsigned(<nFieldNo> | <cFieldName>) --> lUnsigned
позиция поля в списке полей
имя поля
.T. если поле беззнаковое; .F. - в противном случае.
FieldUnsigned() используется для определения, является ли поле беззнаковым.
? rs:FieldUnsigned("salary") // .T.
GetValue(<nFieldNo> | <cFieldName>) --> xValue
позиция поля в списке полей
имя поля
Значение поля текущей строки.
GetValue() используется для определения значения заданного поля текущей строки.
? rs:GetValue('fname') // John
GoBottom() --> NIL
GoBottom() перемещает указатель к последней логической строке.
Если набор был создан в режиме 'загрузка по требованию' (<lNoFetch>==.T.), то предварительно дозагружаются все оставшиеся записи.
rs:CreateRowset("SELECT * FROM mytable",,,,,,,,,.T.) ? rs:Recno() // 1 ? rs:Lastrec() // 0 (there remain unfetched rows) rs:GoBottom() ? rs:Recno() // number of selected rows ? rs:Lastrec() // number of selected rows (no unfetched rows remain)
Goto(<nRowPosition>) --> nNewPosition
номер строки
Новый номер текущей строки.
Goto() используется для перемещения к строке с заданным номером.
Если <nRowPosition> меньше 1, Goto() перемещает указатель к строке с номером 1 и состояние Bof() устанавливается в .T. Если <nRowPosition> больше, чем Lastrec(), Goto() перемещает указатель к последней физической строке, и состояние Eof() устанавливается в .T.
for i:=1 to rs:Lastrec() rs:goto(i) ? rs:Read() next
GoTop() --> NIL
GoTop() перемещает указатель к первой логической строке.
rs:CreateRowset("SELECT fname,lname FROM mytable") ? rs:Recno() // 1 rs:CreateOrder("fname","fname",20) rs:SetOrder("fname") rs:GoTop() ? rs:Recno() // the position of first logical row
KeyNo() --> nPosition
Логический номер текущей строки.
KeyNo() используется для определения логического номера текущей строки. Если нет управляющего индекса (созданного методом TRowset:CreateOrder() и установленного управляемым методом TRowset:SetOrder()), KeyNo() возвращает физический номер строки, то есть имеет тот же эффект, что и метод TRowset:Recno().
rs := conn:CreateRowset("SELECT fname,lname FROM mytable") rs:CreateOrder("fname","fname",20) ? rs:KeyNo(), rs:Recno() // 1, 1 (no controlling order) rs:SetOrder("fname") // set controlling order by fname ? rs:KeyNo(), rs:Recno() // N, 1 rs:GoTop() ? rs:KeyNo(), rs:Recno() // 1, M
Lastrec() --> nLastrec
Количество строк в наборе.
Lastrec() возвращает количество строк в наборе.
Если набор был создан в режиме 'загрузка по требованию' (параметр <lNoFetch> конструктора TConnect:CreateRowset() - .T.), Lastrec() может возвращать 0 (когда загружены не все записи). Количество загруженных строк можно определить с помощью метода TRowset:Fetched(). Для дозагрузки оставшихся записей можно использовать метод TRowset:FetchAll(). После этого Lastrec(), будет возвращать действительноеколичество строк в наборе.
rs := conn:CreateRowset("SELECT * FROM mytable",,,,,,,,,.T.) ? rs:Lastrec() // 0 rs:FetchAll() ? rs:Lastrec() // number of selected rows
NFields() --> nFields
Количество полей в наборе.
NFields() используется для определения количества полей в строках набора.
rs := conn:CreateRowset("SELECT fname,lname FROM mytable") ? rs:NFields() // 2
Read() --> oRow
Объект, содержащий все поля текущей строки.
Read() получает значения всех полей текущей строки и помещает их в одноименные атрибуты возвращаемого объекта.
rs := conn:CreateRowset("SELECT fname,lname FROM mytable") ? rs:Read():fname // John ? rs:Read():lname // Smith
Recno() --> nPosition
Физический номер текущей строки.
Recno() используется для определения физического номера текущей строки. Если в наборе не ни одной строки, возвращается 0.
rs := conn:CreateRowset("SELECT * FROM mytable") ? rs:Recno() // 1 rs:Skip() ? rs:Recno() // 2 rs:Goto(100) ? rs:Recno() // 100
RefreshAll() --> nLastrec
Количество строк в наборе.
RefreshAll() обновляет набор строк путем повторного выполнения <cSelectSQL>, переданного конструктору класса TRowset (TConnect:CreateRowset()), с использованием параметров SQL, переданных в <aParameters>. Указатель остается на строке с тем же физическим номером, или перемещается к последней физической строке.
rs := conn:CreateRowset("SELECT * FROM mytable") rs:Browse() rs:RefreshAll() rs:Browse()
RefreshCurrent() --> NIL
RefreshCurrent() обновляет текущую строку набора путем выполнения <cRefreshSQL>, переданного конструктору TConnect:CreateRowset(). Если <cRefreshSQL> - NIL, RefreshCurrent() ничего не делает.
rs := conn:CreateRowset("SELECT id,fname,lname FROM mytable",,,,,; "SELECT id,fname,lname FROM mytable WHERE id=:id") ? rs:Read() rs:RefreshCurrent() ? rs:Read()
Seek(<xKeyValue>,[<lSoft>]) --> lFound
значение ключа искомой строки
логическое значение определяющее режим относительного поиска. Это определяет, куда будет установлен указатель, если строка с заданным ключом не найдена (см. ниже)
.T. если строка с заданным ключом найдена; .F. - в противном случае
Seek() ищет первую логическую строку с ключом, равным <xKeyValue>. Если такая строка найдена, она становится текущей и Seek() возвращает .T.; иначе возвращается .F. и указатель перемещается следующим образом: при нормальном (не относительным) поиске указатель перемещается к последней логической строке и TRowset:Eof() возвращает .T.; при относительном поиске указатель перемещается к первой строке, ключевое значение которой больше чем заданное. Если такой строки не существует, указатель перемещается к последней логической строке и TRowset:Eof() возвращает .T.
Если нет управляющего индекса (созданного при помощи метода TRowset:CreateOrder() и установленного управляющим при помощи метода TRowset:SetOrder()),Seek() ничего не делает.
rs := conn:CreateRowset("SELECT fname,lname FROM mytable") rs:CreateOrder("fname","fname",20) rs:SetOrder("fname") ? rs:Seek("John")
SetOrder([<cOrderName>]) --> cOrderName
имя индекса, который должен стать управляющим
Имя текущего управляющего индекса или NIL (если нет управляющего индекса).
SetOrder() устанавливает индекс, созданный методом TRowset:CreateOrder(), управляющим. Возвращается имя ранее управляющего индекса.
Если передана пустая строка, SetOrder() снимает управляющий индекс, и доступ к строкам набора осуществляется в физическом порядке.
rs := conn:CreateRowset("SELECT fname,lname FROM mytable") rs:CreateOrder("fname","fname",20) rs:Browse() // browse rows in physical order rs:SetOrder("fname") rs:Browse() // browse rows ordered by first name rs:SetOrder("") rs:Browse() // browse in physical order again
SetValue(<nFieldNo> | <cFieldName>, <xValue>) --> NIL
позиция поля в списке полей
имя поля
новое значение поля
SetValue() присвает значение <xValue> заданному полю текущей строки.
![]() | В отличие от метода TRowset:Write() SetValue() не инициирует немедленного отражения изменения на SQL сервере (выполнения оператора <cUpdateSQL>, переданного конструктору класса TRowset TConnect:CreateRowset()). Отражение производится при первом же вызове метода, перемещающего указатель. |
rs := conn:CreateRowset("SELECT fname,lname FROM mytable") ? rs:GetValue("fname") // John rs:SetValue("fname","Sean") ? rs:GetValue("fname") // Sean
Skip([<nRows>]) --> nRows
количество логических строк, на которое должен переместиться указатель относительно текущей строки. Положительное значение означает перемещение в прямом направлении, отрицательное - в обратном. По умолчанию 1
Действительное число строк, на которое переместился указатель.
Skip() перемещает указатель в прямом или обратном направлении относительно текущей строки. При попытке переместить указатель в прямом направлении за последнюю логическую строку, указатель становится на последнюю логическую строку и TRowset:Eof() возвращает .T. При попытке переместить указатель в обратном направлении за первую логичускую строку, указатель становится на первую логическую строку и TRowset:Bof() возвращает .T.
rs := conn:CreateRowset("SELECT * FROM mytable") while !rs:Eof() ? rs:Read() rs:Skip() enddo
Write(<oRow>) --> NIL
объект, содержащий новые значения полей
Write() присваивает новые значения полям текущей строки. Производится попытка отразить изменения на SQL сервере путем выполнения оператора <cUpdateSQL>, переданного конструктору класса TRowset TConnect:CreateRowset().
rs := conn:CreateRowset("SELECT id,fname,lname FROM mytable",,,,; "UPDATE mytable SET fname=:fname,lname=:lname WHERE id=:id") oRow := map() oRow:fname := "John" oRow:lname := "Smith" rs:Write(oRow) ? rs:GetValue("fname") // John ? rs:GetValue("lname") // Smith
Пред. | Начало | След. |
Краткий курс | Уровень выше | Особенности СУБД |