powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Произвольное предложение WHERE в REMOTE VIEW...
3 сообщений из 3, страница 1 из 1
Произвольное предложение WHERE в REMOTE VIEW...
    #32721073
___DenisKa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет!

Вначале опишу то, что дано:
есть справочник корреспондентов, состоящий из нескольких таблиц (предприятия; должности на этих предприятиях; сотрудники, занимающие эти должности и т.д.)
Для отображения этой информации используецца несколько remote view. Некоторые из них обновляемые и это их достоинство не хочецца терять .
Но данных ОЧЕНЬ много, посему если сразу все вываливать на клиента,
то справочник работает очень долго.
Посему хочу открывать справочник ПУСТЫМ, а потом пользователь сам укажет по каким критериям он хотел бы выбирать данные (отбор может проводицца по нескольким полям).
Для отбора использую свой объект, который на выходе выдает строку вида:
Код: plaintext
EnterpriseName like '%ООО%' and CityName like '%Новгород%' and Address like '%Горького%'

Подскажите плиз, многоуважаемые, можно ли добицца следующей вещи:
создать remote view (желательно ОБНОВЛЯЕМОЕ), которое бы выглядело примерно так:

Код: plaintext
1.
2.
CREATE SQL VIEW vAddress REMOTE CONNECTION conMain SHARE AS ;
SELECT * FROM vAddress ;
WHERE ?lcWhere

где в качестве lcWhere можно было бы подставить вышеуказанную строку фильтра?

ЗЫ если кто-то скажет, что данное view не будет обновляемым никогда, то оговорюсь, что это лишь пример, на самом деле есть remote view , выбирающие данные из одной таблицы и которые хочецца также параметризовать по нескольким произвольным полям этой таблицы...
...
Рейтинг: 0 / 0
Произвольное предложение WHERE в REMOTE VIEW...
    #32721207
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 ___DenisKa

Эх, сложную ты очень тему поднимаешь :(

Попробую лишь очень кратко описать как я это делаю:

1) RV пишется с условием WHERE 1=1. Дальнейшее как обычно - т.е. поля назначаются ключевыми, обновляемыми и т.д.

2) Пользуются следующие 2 функции:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
PROCEDURE Use_RV
LPARAMETERS tcViewName, tcAlias, tcWhere
LOCAL lcAlias, lcSQL, lnConnHandle, lcTables, ;
 lcKeyFieldList, lcUpdatableFieldList, lcUpdateNameList
m.lcAlias = m.tcAlias + "_template"
IF USED (m.lcAlias)
 USE IN (m.lcAlias)
ENDIF
DO CASE
CASE INDBC (m.tcAlias, "VIEW") AND ;
  DBGETPROP (m.tcAlias, "VIEW", "SOURCETYPE") =  1 
 * Локальное представление
 LOCAL lcWhere
 m.lcWhere = m.tcWhere
 USE (m.tcViewName) IN  0  ALIAS (m.tcAlias) SHARED
 RETURN .T.
CASE INDBC (m.tcAlias, "TABLE")
 * Таблица
 USE (m.tcViewName) IN  0  ALIAS (m.tcAlias) SHARED
 RETURN .T.
ENDCASE

USE (m.tcViewName) IN  0  NODATA ALIAS (m.lcAlias)
* Извлекаем то что есть в RV
m.lcSQL = CURSORGETPROP ("SQL", m.lcAlias)
m.lnConnHandle = CURSORGETPROP ("ConnectHandle", m.lcAlias)
m.lcTables = CURSORGETPROP ("Tables", m.lcAlias)
m.lcKeyFieldList = CURSORGETPROP ("KeyFieldList", m.lcAlias)
m.lcUpdatableFieldList = CURSORGETPROP ("UpdatableFieldList", m.lcAlias)
m.lcUpdateNameList = CURSORGETPROP ("UpdateNameList", m.lcAlias)
IF USED (m.tcAlias)
 USE IN (m.tcAlias)
ENDIF
SELECT  0 
IF " WHERE " $ UPPER (m.lcSQL)
 m.lnRes = SQLEXEC (m.lnConnHandle, ;
  STRTRAN (m.lcSQL, " WHERE " , " WHERE (" + m.tcWhere + ") AND ", ;
   1 ,  1 ,  1 ), m.tcAlias)
ELSE
 m.lnRes = SQLEXEC (m.lnConnHandle, m.lcSQL + " WHERE " + m.tcWhere, m.tcAlias)
ENDIF
IF m.lnRes <  1 
 MESSAGEBOX ("Ошибка получения данных с сервера")
 RETURN .F.
ENDIF
CURSORSETPROP ("Tables", m.lcTables, m.tcAlias)
CURSORSETPROP ("KeyFieldList", m.lcKeyFieldList, m.tcAlias)
CURSORSETPROP ("UpdatableFieldList", m.lcUpdatableFieldList, m.tcAlias)
CURSORSETPROP ("UpdateNameList", m.lcUpdateNameList, m.tcAlias)
CURSORSETPROP ("SendUpdates", .T., m.tcAlias)
RETURN .T.
ENDPROC

PROCEDURE Requery_RV
LPARAMETERS tcAlias, tcWhere
IF PCOUNT () >  2  OR ;
  (PCOUNT() >  0  AND VARTYPE (m.tcAlias) # "C") OR ;
  (PCOUNT() =  2  AND VARTYPE (m.tcWhere) # "C")
 ERROR  11 
 RETURN .F.
ENDIF
IF PCOUNT() =  0 
 IF EMPTY (ALIAS ())
  ERROR  52 
  RETURN .F.
 ELSE
  m.tcAlias = ALIAS ()
 ENDIF
ENDIF
IF PCOUNT() <  2 
 m.tcWhere = "1 = 1"
ENDIF
IF USED (m.tcAlias)
 DO CASE
 CASE CURSORGETPROP ("SourceType", m.tcAlias) =  1 
  * Локальное представление
  LOCAL lcWhere
  m.lcWhere = m.tcWhere
  RETURN REQUERY(m.tcAlias) =  1 
 CASE CURSORGETPROP("SourceType", m.tcAlias) =  102 
  * Удалённое представление через CA
  PRIVATE pcWhere
  m.pcWhere = m.tcWhere
  RETURN REQUERY(m.tcAlias) =  1 
 CASE CURSORGETPROP ("SourceType", m.tcAlias) =  3 
  * Таблица
  ERROR  1536 
  RETURN .F.
 ENDCASE
ENDIF
LOCAL lcTemplateAlias, lcViewName, lnBuffering
m.lcTemplateAlias = m.tcAlias + "_template"
IF !USED (m.tcAlias) AND !USED (m.lcTemplateAlias)
 ERROR  13 , m.tcAlias
 RETURN .F.
ENDIF
IF USED (m.lcTemplateAlias)
 * Есть открытый шаблон
 IF CURSORGETPROP ("SourceType", m.lcTemplateAlias) =  3 
  ERROR  1536 
  RETURN .F.
 ENDIF
 IF CURSORGETPROP ("SourceType", m.lcTemplateAlias) #  2  OR ;
   EMPTY (CURSORGETPROP ("SourceName", m.lcTemplateAlias))
  ERROR "Неверный шаблон - нужно удалённое представление"
  RETURN .F.
 ENDIF
 * Если проверки прошли, значит имеется "правильный" шаблон
 m.lnBuffering = CURSORGETPROP ("Buffering", m.lcTemplateAlias)
ELSE
 * Не найден открытый шаблон
 IF CURSORGETPROP ("SourceType", m.tcAlias) =  3 
  ERROR  1536 
  RETURN .F.
 ENDIF
 IF CURSORGETPROP ("SourceType", m.tcAlias) #  2  OR ;
   EMPTY (CURSORGETPROP ("SourceName", m.tcAlias)) OR ;
   EMPTY (CURSORGETPROP ("Database", m.tcAlias))
  ERROR "Неверный шаблон - нужно удалённое представление"
  RETURN .F.
 ENDIF
 * Сделаем "правильный" (в т.ч. по алиасу) шаблон
 m.lcViewName = JUSTSTEM (CURSORGETPROP ("Database", m.tcAlias)) + "!" + ;
   CURSORGETPROP ("SourceName", m.tcAlias)
 USE (m.lcViewName) IN  0  NODATA ALIAS (m.lcTemplateAlias)
 * Закроем "старый" алиас удалённого представления, чтобы он не мешал следующему коду...
 m.lnBuffering = CURSORGETPROP ("Buffering", m.tcAlias)
 USE IN (m.tcAlias)
ENDIF
* Попробуем проверить SPT-курсор
IF USED (m.tcAlias)
 IF CURSORGETPROP ("SourceType", m.tcAlias) =  3 
  ERROR  1536 
  RETURN .F.
 ENDIF
 IF CURSORGETPROP ("SourceType", m.tcAlias) #  2  OR ;
   !EMPTY (CURSORGETPROP ("SourceName", m.tcAlias))
  ERROR "Неверный SPT-курсор " + m.tcAlias
  RETURN .F.
 ENDIF
 * Теперь можно утверждать что m.tcAlias это SPT-курсор
 IF (CURSORGETPROP ("Buffering", m.tcAlias) =  3  AND ;
   GETFLDSTATE (- 1 , m.tcAlias) # REPLICATE ("1", FCOUNT (m.tcAlias) +  1 )) OR ;
   (CURSORGETPROP ("Buffering", m.tcAlias) =  5  AND ;
   GETNEXTMODIFIED ( 0 , m.tcAlias, .T.) #  0 )
  ERROR  1545 , m.tcAlias
  RETURN .F.
 ENDIF
ENDIF
* Теперь всё проверено и готово к перезапросу.
LOCAL lcSQL, lnConnHandle, lcTables, ;
 lcKeyFieldList, lcUpdatableFieldList, lcUpdateNameList
* Извлекаем то что есть в RV
m.lcSQL = CURSORGETPROP ("SQL", m.lcTemplateAlias)
m.lnConnHandle = CURSORGETPROP ("ConnectHandle", m.lcTemplateAlias)
m.lcTables = CURSORGETPROP ("Tables", m.lcTemplateAlias)
m.lcKeyFieldList = CURSORGETPROP ("KeyFieldList", m.lcTemplateAlias)
m.lcUpdatableFieldList = CURSORGETPROP ("UpdatableFieldList", m.lcTemplateAlias)
m.lcUpdateNameList = CURSORGETPROP ("UpdateNameList", m.lcTemplateAlias)
SELECT SELECT (m.tcAlias) && Чтобы не вызвать ошибку если нет открытого курсора
USE && Закроем явно
IF " WHERE " $ UPPER (m.lcSQL)
 m.lnRes = SQLEXEC (m.lnConnHandle, ;
  STRTRAN (m.lcSQL, " WHERE " , " WHERE (" + m.tcWhere + ") AND ", ;
   1 ,  1 ,  1 ), m.tcAlias)
ELSE
 m.lnRes = SQLEXEC (m.lnConnHandle, m.lcSQL + " WHERE " + m.tcWhere, m.tcAlias)
ENDIF
IF m.lnRes <  1 
 ERROR "Ошибка получения данных с сервера"
 RETURN .F.
ENDIF
CURSORSETPROP ("Tables", m.lcTables, m.tcAlias)
CURSORSETPROP ("KeyFieldList", m.lcKeyFieldList, m.tcAlias)
CURSORSETPROP ("UpdatableFieldList", m.lcUpdatableFieldList, m.tcAlias)
CURSORSETPROP ("UpdateNameList", m.lcUpdateNameList, m.tcAlias)
CURSORSETPROP ("SendUpdates", .T., m.tcAlias)
CURSORSETPROP ("Buffering", m.lnBuffering, m.tcAlias)
CURSORSETPROP ("Buffering", m.lnBuffering, m.lcTemplateAlias)
RETURN .T.
ENDPROC

Как видишь реально работает SPT запрос (прямой запрос), но его курсор делается "обновляемым" - т.е. потом можно пользовать TableUpdate()/TableRevert() Вместо Requery() пользуется соответствующая функция. Use_RV() можно и вообще никогда не пользовать.

У меня на формах в DE ложатся именно RV, только им ставится свойство Nodata - чтоб они данные не тянули. А уж по ходу инициализации формы - где-то там на Init формы или даже позже проводится их перезапрос по Requery_RV("alias", m.lcWhere).

Ессно что в такой схеме проявляется проблема разрушения гридов (реально ведь курсор пересоздаётся а не "перезаполняется") - но как я надеюсь если ты уже дорос до столь серьёзных вопросов, то эта проблема тебя не должна беспокоить :) способы её решения общеизвестны...

Posted via ActualForum NNTP Server 1.0
...
Рейтинг: 0 / 0
Произвольное предложение WHERE в REMOTE VIEW...
    #32728997
___DenisKa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как говорицца: автор"Все гениальное - просто!" ©
Посему я, не мудрствуя лукаво, решил, что я для выборки и отображения данных буду использовать прямые запросы, где построить динамическое предложение WHERE - как "конфетку у ребенка ..." ©, а вот для редактирования конкретного корреспондента (карточки его), будет вызывацца другая форма, специально под ето дело заточенная...
Таким образом я убиваю 2-х зайцев:
1. я получаю гибкую, быструю и удобную для поиска форму для поиска и выбора справочника, где для поиска я собираюсь использовать свой чудо-алгоритм поиска с учетом индекса релевантности, ранее уже описанный мной в форуме по MS SQL (ссылку не приведу - давно дело было...)
2. я получаю гибкую, быструю и удобную для редактирования форму для редактирования.
Ессно внешний вид у них будет координально отличацца, текущий внешний вид и функциональность убога и медленна, как и все универсальное...
Тем не менее, огромное спасибо за ответ - интересное решение!
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Произвольное предложение WHERE в REMOTE VIEW...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]