powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Один массив в нескольких запросах
16 сообщений из 16, страница 1 из 1
Один массив в нескольких запросах
    #37754521
Всем доброго. Мне удобно было бы выполнить десяток update запросов, в которые я подставляю одинаковые данные в качестве критерия поиска:
Код: sql
1.
2.
3.
4.
5.
a=(1,2,3)
update D set поле=значение WHERE другоеполе in a
update В set поле=значение WHERE другоеполе in a
update С set поле=значение WHERE другоеполе in a
...


Где под a подразумевается некий массив. Т. е ху избежать вот такой писанины:
Код: sql
1.
2.
3.
4.
update D set поле=значение WHERE другоеполе in (1,2,3)
update В set поле=значение WHERE другоеполе in (1,2,3)
update С set поле=значение WHERE другоеполе in (1,2,3)
...


Поскольку в списке критерия поиска будет много значений, хотелось бы их ввести один раз в программе.

Каким образом в Фокспро можно описывать такие массивы и подставлять в качестве аргумента командам?
Если возможно покажите пример или ссылку на чтиво.
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754603
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если "по правильному", то создается временная таблица, содержащая нужные значения и затем используется в опции IN. Это будет примерно так

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
* Создается временная таблица. В терминах FoxPro - курсор
create cursor curIn (Field1 i)
insert into curIn (Field1) values (1)
insert into curIn (Field1) values (2)
insert into curIn (Field1) values (3)

update D set поле=значение WHERE другоеполе in (select Field1 from curIn)
update В set поле=значение WHERE другоеполе in (select Field1 from curIn)
update С set поле=значение WHERE другоеполе in (select Field1 from curIn)
...


Хотя в FoxPro возможны и различные "обходные" маневры. Я так думаю, другие посетители форума не удержаться и накидают этих самых "обходных" способов. Но, я бы не советовал их использовать. Опыт, конечно, приобретешь, но нигде, кроме как в FoxPro он не пригодится. А описанный выше способ применим практически во всех языках программирования так или иначе использующий диалект Select-SQL. Ну и в СУБД это будет работать, если там есть понятие временной таблицы.
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754612
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМЯ так думаю, другие посетители форума не удержаться и накидают этих самых "обходных" способов. Но, я бы не советовал их использовать.
Нехороший совет. Не знаешь что напишут, но уже советуешь не читать. Напишут глупостей - тогда и покритикуешь.

В фоксе конструкция "WHERE другоеполе in (...)" не оптимизирована, происходит перебор всех записей таблицы, не используется индекс по "другоеполе", если такой индекс есть то может так оказаться что выполнить отдельный UPDATE для каждого значения гораздо быстрее чем обновить разом.
Надо замерять скорость на конкретных данных, попробуй так:
* Создается временная таблица. В терминах FoxPro - курсор
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create cursor curIn (Field1 i)
insert into curIn (Field1) values (1)
insert into curIn (Field1) values (2)
insert into curIn (Field1) values (3)

sele curIn
scan
   update D set поле=значение WHERE другоеполе = curIn.Field1
   update В set поле=значение WHERE другоеполе = curIn.Field1
   update С set поле=значение WHERE другоеполе = curIn.Field1
endscan


при таком подходе курсор не обязательно делать, можно массив так же перебрать по одному элементу.
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754619
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВ фоксе конструкция "WHERE другоеполе in (...)" не оптимизирована, происходит перебор всех записей таблицы, не используется индекс по "другоеполе"[/src]
при таком подходе курсор не обязательно делать, можно массив так же перебрать по одному элементу.

А проверить

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SET DELETED off

CREATE CURSOR test (f1 int, f2 int)

INSERT INTO test VALUES (1,1)
INSERT INTO test VALUES (1,2)
INSERT INTO test VALUES (1,3)

SELECT test 
INDEX on f2 TAG f2

SYS(3054,11)

UPDATE test SET f1 = 4 WHERE f2 in (1,3)

SET DELETED ON 

BROWSE 
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754620
ВладимирМЕсли "по правильному", то создается временная таблица
Спасибо конечно, но эта задача разовая. Я сначала так и думал, но оказалось проще просто запросами в Command рулить.
а так как в Коммандах можно только одну строку выполнить, я подумал что мне проще будет минипрогу написать, тем паче что в случае с фоксом это легко и просто.

авторНадо замерять скорость на конкретных данных
Не надо. В моем случае. Чего там - десяток несчастных таблиц по 1000 записей. Короче скорость у меня вполне приемлема получается. Повторюсь - задача разовая, меня устроит и выполнение запросов в Command, так что над оптимизацией заморачиваться нет желания.

Хотелось бы чтоб лисичка меня понимала, но похоже я требую от нее больше чем можно.
Хотя думаю ей бы не помешала возможность таким образом определять списки в программах - в одну строку константно
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754635
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWistА проверить
А подумать?
Один уже так проверял, почитай чего напроверял .
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754656
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Виталий БеликВладимирМЕсли "по правильному", то создается временная таблица
Спасибо конечно, но эта задача разовая. Я сначала так и думал, но оказалось проще просто запросами в Command рулить.
а так как в Коммандах можно только одну строку выполнить, я подумал что мне проще будет минипрогу написать, тем паче что в случае с фоксом это легко и просто.
Начиная с VFP6 в окне Command можно выполнить несколько команд сразу. Надо просто предварительно выделить тот блок, который собираешься выполнить и нажать Enter. Будет выполнен весь выделенный кусок как одна процедура.

Кстати, непонятно, какое отношение к этому имеют временные таблицы. Ведь именно их можно создавать и наполнять по одной команде за раз.
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754661
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВладимирМЯ так думаю, другие посетители форума не удержаться и накидают этих самых "обходных" способов. Но, я бы не советовал их использовать.
Нехороший совет. Не знаешь что напишут, но уже советуешь не читать. Напишут глупостей - тогда и покритикуешь.
Судя по написанному тобой - очень хороший и своевременный

Посмотри на профиль автора темы. Для него FoxPro - просто один из многих языков. Какой смысл объяснять ему нечто, специфическое только и исключительно для этого самого языка. Особенно в свете работы с СУБД совершенно бессмысленно объяснять правила работы с навигационными командами (SCAN). А уж всякие "заморочки" с оптимизацией, индексами и т.д., и т.п. - вообще почти пустой звук.
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754672
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Виталий БеликХотя думаю ей бы не помешала возможность таким образом определять списки в программах - в одну строку константно
Да можно это сделать. Поиск по ключевому слову "макроподстановка". Просто, во-первых, это специфический прием, основанный на том, что FoxPro - это интерпретатор, а не компилятор, а, во-вторых, новичкам пользоваться этим инструментом крайне не желательно. "Эта штука посильнее Фауста Гете" (с). В том смысле, что новички на нее сразу "подсаживаются", а потом начинается дикая "ломка". Аналогия более чем уместна. Очень сильный инструмент которым надо уметь пользоваться. Точнее, уметь НЕ пользоваться (почему - предмет отдельного разговора)

Можно и через массивы. Но опять же, это специфика именно FoxPro. Есть такая функция ASCAN(), которую можно использовать в условиях выборки SQL-запросов.
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754692
авторНадо просто предварительно выделить тот блок, который собираешься выполнить и нажать Enter. Будет выполнен весь выделенный кусок как одна процедура.
Только видимо сначала придется отучиться нажимать Энтер после каждой введенной строки.
авторКстати, непонятно, какое отношение к этому имеют временные таблицы. Ведь именно их можно создавать и наполнять по одной команде за раз.
Это к чему была реплика?
авторКакой смысл объяснять ему нечто, специфическое только и исключительно для этого самого языка.
Думаешь не пойму?
авторновичкам пользоваться этим инструментом крайне не желательно.
Ты же даже не знаешь что мне о Фоксе известно, как же ты можешь судить обо мне?
про Амперсанд-команды я знаю, и иногда использую. В данном случае вопрос скорее о том как объявить массив констант в одну строку (вроде как в Си: int a[]={1,2,3,4,5}), а не как его потом в запросах использовать.
Т.е. если мне как разработчику хочется такого удобства - получу ли я его.
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754745
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TPaulWistА проверить
А подумать?
Один уже так проверял, почитай чего напроверял .

И где репо-код update-а, который необходим ТС ???

в виде:

Код: sql
1.
2.
a=(1,2,3)
update D set поле=значение WHERE другоеполе in a
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754982
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМDima Tпропущено...

Нехороший совет. Не знаешь что напишут, но уже советуешь не читать. Напишут глупостей - тогда и покритикуешь.
Судя по написанному тобой - очень хороший и своевременный

Посмотри на профиль автора темы. Для него FoxPro - просто один из многих языков. Какой смысл объяснять ему нечто, специфическое только и исключительно для этого самого языка. Особенно в свете работы с СУБД совершенно бессмысленно объяснять правила работы с навигационными командами (SCAN). А уж всякие "заморочки" с оптимизацией, индексами и т.д., и т.п. - вообще почти пустой звук.
Это форум по фоксу вообще-то, поэтому не вижу смысла умалчивать наиболее эффективные по производительности решения. Оставь выбор автору вопроса, испугается сканов - не будет использовать. Может наоборот ему понравится? Пусть сам решает.

Я подумал ты на макроподстановку намекал, так сам ее и посоветовал в итоге:
ВладимирМДа можно это сделать. Поиск по ключевому слову "макроподстановка".
Согласен что макроподстановки часто бездумно используют, но тут как раз тот самый случай когда она дает эффект, поэтому вопрос спорный о ее применении в данной конструкции.
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37754983
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Виталий Беликпро Амперсанд-команды я знаю, и иногда использую. В данном случае вопрос скорее о том как объявить массив констант в одну строку (вроде как в Си: int a[]={1,2,3,4,5}), а не как его потом в запросах использовать.
Если знаешь, то тут чего тогда не догадался?
Код: sql
1.
2.
a="1,2,3"
update D set поле=значение WHERE другоеполе in (&a)


"a" это не массив, а строка в данном случае.
Только у данной конструкции есть ограничение на длину строки. Точно не помню сколько символов, но не много.

Что касается объявления массива в одну строку - нет такого в фоксе, массивы тут редко используются, восновном курсоры. Наполнение курсора INSERT`ами по одному на строку, или (если разово руками) написать brow и Ctrl+Y для добавления строки.
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37755130
LUCIAN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Виталий Белик,
Код: sql
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.
*имеется список операций 
SELE 0
CREATE CURSOR SP_OPER (KOP C(2),IOP C(50))
INSERT INTO sp_oper VALUES ("0 ","Все")
INSERT INTO SP_OPER (KOP,IOP) VALUES ('31','Поступление от внешних поставщиков                ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('33','Поступление от подразделений                      ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('36','Списание излишков (структ. подр-ие)               ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('37','Требование накладная со склада на склад           ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('51','Отпуск структ.подразд-ию                          ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('54','Продажа на сторону                                ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('55','Отпуск мат.отв. лицу                              ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('56','Отпуск со склада на склад                         ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('57','Списание убыли                                    ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('58','Списание убыли (структ.подр-ие)                   ')
INSERT INTO SP_OPER (KOP,IOP) VALUES ('82','Отпуск материалов по лимиткам                     ')
 
 
*С помощью LISTBOX делается выбор множества  операций и этот список помещаем в переменную SPIS

SELECT SP_OPER
spis='('
SCAN
	nCnt=RECNO()
	IF This.parent.List1.Selected(nCnt)
		spis=spis+IIF(spis=='(','',',')+kop
	endif	
endscan
spis=spis+')'
IF AT(CHRTRAN(spis,'()',''),'0 ')>0
	SELECT SP_OPER
	spis='('
	SCAN FOR kop # '0 '
		spis=spis+IIF(spis=='(','',',')+kop
	endscan
spis=spis+')'
ENDIF

*ДЕЛАЕМ ОБРАЩЕНИЕ К БД ORACLE
lnConn=SQLSTRINGCONNECT('DRIVER={ORACLE ODBC DRIVER};SERVER=ORA9I;UID=LIDA;PWD=LIDA;DBQ=ORA9I;DBA=W;APA=T;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;FRL=F;MTS=F;CSR=F;PFC=10;TLO=O;')
IF m.lnConn <= 0 && NO Success.
	WAIT WINDOW "КРАХ SQLCONNECT" 
	RETURN
ENDIF	

TEXT  TO lcSQLSelectString ADDITIVE TEXTMERGE NOSHOW  
SELECT  *  FROM LIDA.SNA_DOC WHERE COPE IN <<SPIS>>  AND DDOC BETWEEN (?DATNT) AND (?DATKT) AND (sna_doc.cope <> 0)
ENDTEXT
lnReturn = SQLEXEC(lnConn, lcSQLSelectString, "CDOKS")
= SQLDISCONNECT(lnConn)
IF lnReturn <= 0
	WAIT WINDOW "КРАХ SQLEXEC" 
ENDIF	

* В СЛУЧАЕ БД VFP МОЖНО ТАК
=EXECSCRIPT(lcSQLSelectString)
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37755378
Dima T"a" это не массив, а строка в данном случае.
А-а-а. Вот что я упустил...
Я пытался в А пихнуть массив, а надо было строку. Вот за этот пинок спасибо
...
Рейтинг: 0 / 0
Один массив в нескольких запросах
    #37755994
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Виталий Беликавторновичкам пользоваться этим инструментом крайне не желательно.
Ты же даже не знаешь что мне о Фоксе известно, как же ты можешь судить обо мне?
Могу оценить уровень знаний по профилю участника форума (где чаще всего задаются вопросы), по используемой терминологии и собственно по стилю вопросов. Делаю однозначный вывод, что для Вас FoxPro "не родной" язык программирования. Использовать - используете, но на уровне "читаю со словарем". Не "чувствуете" этот язык программирования.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Один массив в нескольких запросах
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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