Указывает составленную пользователем команду для использования с целью проверки конфликтов обновления или удаления для случая, если значение свойства ConflictCheckType объекта CursorAdapter установлено 4. Редактируемое (Read/write)в design и run time.

Вы можете использовать команду, установленную в свойстве ConflictCheckCmd с "родными", Open Database Connectivity (ODBC), или ActiveX Object (ADO) типами источников данных. При использовании ADO, объект CursorAdapter должен использовать объект ADO Command для SQL операций UPDATE или DELETE. В противном случае, Visual FoxPro сбрасывает значение свойства ConflictCheckCmd.

CursorAdapter.ConflictCheckCmd [= cValue]

Параметры

cValue

Указывает на составленную пользователем командную строку, для дополнения команд (подчеркнуто мной - переводчик) определенных в свойствах UpdateCmd и DeleteCmd для проверки конфликтов обновления или удаления. По умолчанию значение cValue содержит пустую строку.
Замечание переводчика:

Приведенное ниже поясняет использование этого свойства для проверки конфликтов.

Когда вы пытаетесь произвести операцию обновления на источнике данных (например, back-end, такой как SQL Server) функция TableUpdate возвращает результат для обновления курсора, связанного с объектов CursorAdapter. Если произошел конфликт, то данные на сервере могут остаться неизменными, но функция TableUpdate вернет True (.T.) поскольку данные в курсоре, связанном с объектом CursorAdapter обновлены.
Рассмотри ситуацию:

  1. Пользователь 1 открыл курсор на таблице Customer.
  2. Пользователь 2 обновляет запись с номером 1 и совершает транзакцию.
  3. Пользователь 1 обновляет запись с номером 1 с помощью функции TableUpdate

В этой точке мы имеем конфликт обновления: запись на сервере, которую Пользователь1 пытается обновить изменена после того, как она загружена в курсор объекта CursorAdapter.

Приведенный ниже пример программного кода использует проверяющую конфликт команду "CRLF+[EXECSCRIPT("IF _tally=0" + CHR(10) + "ERROR('Update conflict')" + CHR(10) + "ENDIF")]" в дополнение к команде обновления. В этом случае, функция TableUpdate() вернет False (.F.), что позволит вам обслужить конфликт. Сама команда проверки конфликта использована в методе, ассоциированном с событием BeforeUpdate объекта CursorAdapter

Скопировать код тестового примера
#DEFINE CRLF CHR(13)+CHR(10)
Local loCursor,ovfp
CLEAR

ON ERROR

Set Exclusive Off
Close Databases All
Set Multilocks On
loCursor = Createobject('CA')
* Загружаем курсор данными, определенными командой, хранящейся в SelectCmd
* и отображаем сообщение об ошибке, если таковая имеет место быть.
loCursor.CursorFill()
GO top
* Покажем значение поля companyname перед операцией обновления.
? "Before:",companyname
?
ovfp=Createobject("visualfoxpro.application.8")
ovfp.DoCmd("set exclusive off")
ovfp.DoCmd("update (_samples+'\northwind\customers') set companyname='Alfreds Futterkisted' where customerid='ALFKI'")
GO top
* Обновим данные в курсоре.
replace companyname WITH 'Alfreds Futterkiste'
* Обновим данные на сервере.
retval=TABLEUPDATE(0,.F.,locursor.alias)
Messagebox("Tableupdate="+Transform(retval))

* Если имеет место конфликт, отобразим ошибку.
if(retval=.F.)
 LOCAL ARRAY errors(1)
 AERROR(errors)
* Выводим сообщение об ошибке.

 IF "Update conflict"$errors[2]
  MESSAGEBOX("Update Conflict-reverting changes")
  =TABLEREVERT(.T.,locursor.alias)
 ENDIF
endif
 * Обновляем данные (refresh) в курсоре .
loCursor.CursorRefresh()  && Забираем данные назад чтобы убедиться в правильности
GO top
* Отображаем содержание поля companyname после обновление.
?
? "After:",companyname

Define Class CA As CursorAdapter
 Alias = 'test1'
 DataSourceType = 'NATIVE'
 SelectCmd = 'select * from (_samples+"\northwind\customers")'
 Tables = 'Customers'
 KeyFieldList = "customerid"
 UpdatableFieldList = "companyname"
 UpdateNameList = "customerid customers.customerid,companyname customers.companyname"
 WhereType= 3

* Составляем команду проверки конфликта, чтобы обслужить конфликт.
* Сама по себе она ничего не делает
* Далее она просто добавляется к автоматически сгенерированной команде UpdateInsertCmd 
* для проверки - было ли что-либо действительно обновлено.
 ConflictCheckCmd =CRLF+[EXECSCRIPT("IF _tally=0" + CHR(10) + "ERROR('Update conflict')" + CHR(10) + "ENDIF")]

 Procedure AfterUpdate
  Lparameters cFldState, lForce, nUpdateType, UpdateInsertCmd, DeleteCmd, lResult
  * Взглянем на посланную команду UpdateInsertCmd
  ? "Update Command sent="+UpdateInsertCmd
  * Поменяем местами реальные значения в команде, чтобы видеть, что происходит.
  UpdateInsertCmd=Strtran(UpdateInsertCmd,[OLDVAL('customerid','test1')],Oldval('customerid','test1'))
  UpdateInsertCmd=Strtran(UpdateInsertCmd,[OLDVAL('companyname','test1')],Oldval('companyname','test1'))
  UpdateInsertCmd=Strtran(UpdateInsertCmd,[test1.companyname],test1.companyname)
  ? "With the OLDVAL() and test1.companyname evaluated the update statement is :"+UpdateInsertCmd
  * Проверим возврат.
  ? "Tally="+Transform(_Tally)

 Procedure BeforeUpdate
  Lparameters cFldState, lForce, nUpdateType, cUpdateInsertCmd, cDeleteCmd
  cUpdateInsertCmd=cUpdateInsertCmd+this.ConflictCheckCmd
ENDDEFINE

Примечания

Применяется к: классу CursorAdapter

Смотри также