Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема с запросом на обновление

305
18 ноября 2007 года
Kashuk
385 / / 21.02.2003
Есть 2 таблицы:

t1 - склад, где есть товар.
t2 - накладная, для списания части товара со склада.

Хочу cделать запрос на обновлениe:

"UPDATE t1 INNER JOIN t2 ON t1_ID = t2_ID SET t1_Col = t1_Col - t2_Col"

(в аксесе такой код работаeт)
а тут выдаёт ошибку...
использую
BDE-Query

Подскажите как можно реализовать подобное обновление
309
18 ноября 2007 года
el scorpio
1.1K / / 19.09.2006
Цитата:
(в аксесе такой код работаeт) а выдаёт ошибку...
использую BDE-Query


Если БД - ACCESS, то использовать ADO. Более того, можно написать ВСЕ запросы в самом ACCESS (вкладка "Запросы"), и вызвать их по имени через AdoStoredPoc

305
18 ноября 2007 года
Kashuk
385 / / 21.02.2003
Цитата: el scorpio
Если БД - ACCESS, то использовать ADO. Более того, можно написать ВСЕ запросы в самом ACCESS (вкладка "Запросы"), и вызвать их по имени через AdoStoredPoc



Базы не на аксесе, таблицы старые, парадокс 7...

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

3.2K
18 ноября 2007 года
nikipelovav
152 / / 12.04.2006
Цитата: Kashuk
Есть 2 таблицы:

t1 - склад, где есть товар.
t2 - накладная, для списания части товара со склада.

Хочу cделать запрос на обновлениe:

"UPDATE t1 INNER JOIN t2 ON t1_ID = t2_ID SET t1_Col = t1_Col - t2_Col"

(в аксесе такой код работаeт) а выдаёт ошибку...
использую
BDE-Query

Подскажите как можно реализовать подобное обновление



Пиши так,

Код:
TQuery* pQ;

123 - это количество
34 - это код записи (тоже что и уникальный ключ)

pQ->SQL->Add( "UPDATE t1 SET t1_Col = 123 WHERE t1_ID = 34" );

или, используя параметры для хранения значений

pQ->SQL->Add( "UPDATE t1 SET t1_Col = :Quant WHERE t1_ID = :KeyCode" );
pQ->Params->Items[0]->Value = 123;
pQ->Params->Items[1]->Value = 34;
305
18 ноября 2007 года
Kashuk
385 / / 21.02.2003
Цитата: nikipelovav
Пиши так,
Код:
TQuery* pQ;

123 - это количество
34 - это код записи (тоже что и уникальный ключ)

pQ->SQL->Add( "UPDATE t1 SET t1_Col = 123 WHERE t1_ID = 34" );

или, используя параметры для хранения значений

pQ->SQL->Add( "UPDATE t1 SET t1_Col = :Quant WHERE t1_ID = :KeyCode" );
pQ->Params->Items[0]->Value = 123;
pQ->Params->Items[1]->Value = 34;



Так нужно переберать все записи...
Похожим способом я и реализировал, но это не правельно, хотелось бы услышать ответ спецов...

1
19 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: Kashuk
Так нужно переберать все записи...
Похожим способом я и реализировал, но это не правельно, хотелось бы услышать ответ спецов...


Необходимо правильно строить структуру базы. И зачем все записи перебирать?

305
19 ноября 2007 года
Kashuk
385 / / 21.02.2003
Цитата: kot_
Необходимо правильно строить структуру базы. И зачем все записи перебирать?



Подскажи как написать запрос, что б уменьшить количество товара в 1 таблице, на значения товара в 2 таблице.

1
19 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: Kashuk
Подскажи как написать запрос, что б уменьшить количество товара в 1 таблице, на значения товара в 2 таблице.


 
Код:
DELETE FROM table where id in SELECT id from table2

если конечно я тебя правильно понял
305
19 ноября 2007 года
Kashuk
385 / / 21.02.2003
Цитата: kot_
 
Код:
DELETE FROM table where id in SELECT id from table2

если конечно я тебя правильно понял



Несовсем.
Есть 2 таблицы
Т1 - это склад с товаром и таблица
Т2 - Накладная (в эту таблицу клиент наберает товар со склада)
(к примеру он выбрал 5 шт процессоров из 10 и 2 ОЗУ из 15)
При сохранение накладной, количество на складе должно уменьшится, то есть процов должно остаться 5 а ОЗУ 13.

1
19 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: Kashuk
Несовсем.
Есть 2 таблицы
Т1 - это склад с товаром и таблица
Т2 - Накладная (в эту таблицу клиент наберает товар со склада)
(к примеру он выбрал 5 шт процессоров из 10 и 2 ОЗУ из 15)
При сохранение накладной, количество на складе должно уменьшится, то есть процов должно остаться 5 а ОЗУ 13.


мля. юный чел - читай хотябы Дейта. Он писал давно - но то что писал актуально до сих пор.
склад с товаром - чисто ИМХО конечно - но это приходные накладные. Потому как, хоть меня убейте, если товар на склад неоприходован - то хрен ты его спишешь. Второе - та же таблица документов - расходные накладные. Чисто мое понимание - тут как минимум отсутствует еще три таблицы - и никаких проблем быть не может. Простешим запросом - не надо считать количество - надо просто(для MSSQL):

Код:
CREATE PROCEDURE sInsMainDoc
@idtovara int,
...
AS
{
declare @idmaindoc;
set @idmaindoc = NULL
INSERT INTO tableMain (idtovara,idcontragent, data,iddoctype)values(@idtovara,@idcontragent,NOW(),@@iddoctype);
set @idmaildoc = IDENT_CURRENT('tableMain')

}

и далее
для парадокса это делается просто без ХП.
Кроме того - в чем прелесть использования собственно парадокса? Юзайте нормальные сервера БД. Тем более что выбор есть. Учитесь работать нормально а не через ж.
3.2K
19 ноября 2007 года
nikipelovav
152 / / 12.04.2006
Цитата: Kashuk
Так нужно переберать все записи...
Похожим способом я и реализировал, но это не правельно, хотелось бы услышать ответ спецов...



А что в этом "переборе записей" не правильно?

Например, ты в накладную ( таблицу t2 ) заносишь перечень "увозимого со склада" товара, с указаныым количеством. Затем тебе необходимо "утвердить" эту накладную. По логике необходимо для каждой записи из накладной уменьшить количество товара на складе ( в таблице t1 ). А как это сделать иначе? как не перебором всех записей в накладной и изменения соответствующей записи на складе. Неужели существуют какие-то "особо умные SQL запросы" которые сделают всё сами?

1
19 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: nikipelovav
А что в этом "переборе записей" не правильно?

Например, ты в накладную ( таблицу t2 ) заносишь перечень "увозимого со склада" товара, с указаныым количеством. Затем тебе необходимо "утвердить" эту накладную. По логике необходимо для каждой записи из накладной уменьшить количество товара на складе ( в таблице t1 ). А как это сделать иначе? как не перебором всех записей в накладной и изменения соответствующей записи на складе. Неужели существуют какие-то "особо умные SQL запросы" которые сделают всё сами?



Нет не существуют. Существуют люди - которые делают "все сами" - при условии - что у людей руки с плечей растут. Как минимум. Накуя млять, за выражение простите, утверждать накладную? И на куя - говоря языком простым записи перебирать? Не ужели это сложно - и на ХУЯ вся РБД если простое - сответствие моножества множеству - что сложного - ведь просто решается

1
19 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: nikipelovav
А что в этом "переборе записей" не правильно?

Например, ты в накладную ( таблицу t2 ) заносишь перечень "увозимого со склада" товара, с указаныым количеством. Затем тебе необходимо "утвердить" эту накладную. По логике необходимо для каждой записи из накладной уменьшить количество товара на складе ( в таблице t1 ). А как это сделать иначе? как не перебором всех записей в накладной и изменения соответствующей записи на складе. Неужели существуют какие-то "особо умные SQL запросы" которые сделают всё сами?



не правильно в этом переборе одно - логика.

3.2K
20 ноября 2007 года
nikipelovav
152 / / 12.04.2006
Цитата: kot_
Нет не существуют. Существуют люди - которые делают "все сами" - при условии - что у людей руки с плечей растут. Как минимум. Накуя млять, за выражение простите, утверждать накладную? И на куя - говоря языком простым записи перебирать? Не ужели это сложно - и на ХУЯ вся РБД если простое - сответствие моножества множеству - что сложного - ведь просто решается



Уважаемый kot_,

У Вас что, месячные ... ;)
И настроение плохое ...
И Вы "матом" разговариваете ...

----------------------------------------------

Если не затруднит, раскажите пожалуйста про

Цитата:
...если простое - сответствие моножества множеству - что сложного - ведь просто решается



Я на своей работе написал бухгалтерскую программу, которая,
как обсуждалось выше, занимается "перебором" записей. И делает это
уже 7 лет, и как-то не внапряг ... ;)

Учится никогда не поздно!
Если Я не общался с теми кто умнее меня, или не нашёл нужную книгу ... - это конечно "минус" мне, но, повторюсь,
учится никогда не поздно.

Пожалуйста, поподробнее о "сответствие моножества множеству" применительно к SQL и т.п.

11
20 ноября 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата:
Пожалуйста, поподробнее о "сответствие моножества множеству" применительно к SQL и т.п.


SQL операция JOIN (FULL, INNER, LEFT, RIGHT)

3.2K
20 ноября 2007 года
nikipelovav
152 / / 12.04.2006
Цитата: oxotnik333
SQL операция JOIN (FULL, INNER, LEFT, RIGHT)



Об этих операторах SQL мне известно и я их использую в своей программе. Я думаю, kot_ говорит о чём-то другом ...

Давайте поговорим об этом на примере бухгалтерии.

Таблица TOVAR : (товар)
int TovarID - код записи, он же уникальный код товара
char TovarName - наименование товара

Таблица NALICHIE: ( наличие )
int NalichieID - код записи
int NalichieTovarID - код товара
int NalichieTovarQuantity - количество

Таблица NAKLADNAYA : (накладная)
int NakladnayaID - код записи
int NakladnayaTovarID - код товара
int NakladnayaTovarQuantity - количество товара
bool NakladnayaSet - признак "проведенной" записи


Чтобы увидеть накладную о "Перевозке товара со склада" используем
SQL с оператором JOIN

 
Код:
SELECT * FROM "TOVAR" T
INNER JOIN "NAKLADNAYA" N
ON T.TovarID = N.NakladnayaTovarID
ORDER BY T.TovarName


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

Но это лишь "подготовленная" накладная. Чтобы она вступила в силу,
необходимо произвести уменьшение количества товара в таблице NALICHIE.

Для этого в цикле выполним модификации записей в таблице NALICHIE и NAKLADNAYA используя SQL с оператором UPDATE
Код:
TQuery *Data = ... - указатель на объект TQuery с данными накладной
TQuery *Upd  = ... - указатель на объект TQuery для модификации данных

for (int i = 0; i < RecordCount; i++)
{
   // если запись не "проведена"
   if ( !Data->FieldByName( NakladnayaSet )->AsBoolean )
    {
       // Шаг 1 - уменьшим кол-во в наличии на складе

       Upd->Close();
       Upd->SQL->Clear();
       Upd->SQL->Add( "UPDATE  NALICHIE SET" );
       Upd->SQL->Add( "NalichieTovarQuantity = NalichieTovarQuantity - :TQuant" );      
       Upd->SQL->Add( "WHERE NalichieTovarID = :TID" );
       
       // через параметры присвоим значения количества и кода записи
       Upd->Params->Items[0]->Value = Data->FieldByName( NakladnayaTovarQuantity )->AsInteger;
       Upd->Params->Items[1]->Value = Data->FieldByName( NakladnayaTovarID )->AsInteger;

       Upd->ExecSQL();

       // Шаг 2 - установим признак "проведено" для записи в накладной
       //            чтобы избежать повторения этой операции
       Upd->Close();
       Upd->SQL->Clear();
       Upd->SQL->Add( "UPDATE  NAKLADNAYA   SET" );
       Upd->SQL->Add( "NakladnayaSet = true" );      
       Upd->SQL->Add( "WHERE NakladnayaID = :NID" );
       
       // через параметры присвоим значение кода записи
       Upd->Params->Items[0]->Value = Data->FieldByName( NakladnayaID )->AsInteger;

       Upd->ExecSQL();
    }
}


То, что описано в цикле, Я назваю "перебором" записей.

Если Я правильно понял kot_-а, существует более красивое и "современное" решение подобной задачи. Вот об этом решении Я и прошу его написать. ;)
11
20 ноября 2007 года
oxotnik333
2.9K / / 03.08.2007
Upd->SQL->Add( "UPDATE NAKLADNAYA SET" );
Upd->SQL->Add( "NakladnayaSet = true" );
Upd->SQL->Add( "WHERE NakladnayaID = :NID" );

// через параметры присвоим значение кода записи
Upd->Params->Items[0]->Value = Data->FieldByName( NakladnayaID )->AsInteger;

Upd->ExecSQL();


вот это можно одним запросом сделать, ане перебором

т.е. примерно так: WHERE NAKLADNAYA.NakladnayaID = Data.NakladnayaID
3.2K
20 ноября 2007 года
nikipelovav
152 / / 12.04.2006
Цитата: oxotnik333
Upd->SQL->Add( "UPDATE NAKLADNAYA SET" );
Upd->SQL->Add( "NakladnayaSet = true" );
Upd->SQL->Add( "WHERE NakladnayaID = :NID" );

// через параметры присвоим значение кода записи
Upd->Params->Items[0]->Value = Data->FieldByName( NakladnayaID )->AsInteger;

Upd->ExecSQL();


вот это можно одним запросом сделать, ане перебором

т.е. примерно так: WHERE NAKLADNAYA.NakladnayaID = Data.NakladnayaID



Не совсем понял как связать текст SQL запроса с объектом TQuery.
Можешь полный код привести?

11
20 ноября 2007 года
oxotnik333
2.9K / / 03.08.2007
полный не смогу, т.к. в бухгалтерии не силен...
но в общем и целом
Upd->SQL->Add( "WHERE NakladnayaID = :NID" );
Upd->Params->Items[0]->Value = Data->FieldByName( NakladnayaID )->AsInteger;
вот эти 2 строчки с перебором всей таблицы заменяются на условие SQL запроса (который написал выше) и он делает это одним махом
11
20 ноября 2007 года
oxotnik333
2.9K / / 03.08.2007
вот в аксессе накидал... есть таблица с товарами и есть накладная в которую забиваются записи из товаров (т.е. они связаны по ключу)
выполняем запрос и таблица (поле количество) товаров уменьшается на количество указанное в накладной:
 
Код:
UPDATE Tovar
  INNER JOIN Naklad
  ON Tovar.Id=Naklad.Id
SET Tovar.CountTov = Tovar.CountTov-Naklad.CountTov;


хы... от чего ушли, к тому и пришли :D
11
20 ноября 2007 года
oxotnik333
2.9K / / 03.08.2007
вот под ANSI SQL (на MS SQLServer2005 работает)

UPDATE Tovar
SET CountTov = Tovar.CountTov - Naklad.CountTov
FROM Naklad INNER JOIN
Tovar ON Naklad.Id = Tovar.Id

а вообще в любой нормальной СУБД есть SQL designer
с ним можно и не знать совсем языка, он сам все сделает
1
20 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: nikipelovav

Если Я правильно понял kot_-а, существует более красивое и "современное" решение подобной задачи. Вот об этом решении Я и прошу его написать. ;)


Зачем в базе таблица NALICHIE? В двух местах хранить одни и те же данные? Это не просто "не современно" как вы изволили выразится - это прямой путь к возникновению ошибок.
Если в двух словах - вполне стандартное решение - сделать две зависимые таблицы - одна - ведущая должна содержать данные по накладной (номер,дата, тип документа и пр.) что может быть отнесено к классу документа. По внешнему ключу (идентификатор) таблица связывается с таблицами записей которая содержит все что относится к классу записи накладной (идентификатор записи,идентификатор документа, идентификатор товара, количество и т.д.). Справочник типов документов в простейшем случае содержит идентификатор типа документа(внешний ключ на таблицу накладных) ну и название. Пример 0- приходная накладная, 1- Расходная накладная, 2 - другие ...
Тогда операция расхода/прихода выполняется посути операцией вставки в таблицу документов записи о документе и добавление в связанную таблицу необходимое количество товара. Количество товара на складе - разница между приходом и расходом. Для оптимизации запроса - что бы не лопатить таблицу от начала времен - можно ввести понятие периода и т.д. но это уже оптимизация последнего этапа.
Т.е. что имеем - создается ХП выполняющюю вставку записи о накладной и возврат нового идентификатора - можно обойтись и просто запросом получив максимальный идентити и увеличив его на 1.
Затем по событию на форме товар добавляется одним запросом - без переборов и пр. Если в логике программы есть необходимость провести накладную, а в бухгалтерии это как раз бывает нужно, то по нажатию на кнопку "провести" выполняется апдейт одной записи по ее идентификатору.
И где здесь перебор всех записей? Эта схема в реальной программе может быть значительно улучшена - просто нет времени - и объяснять долго. Читайте книжки.

3.2K
21 ноября 2007 года
nikipelovav
152 / / 12.04.2006
Цитата: kot_
Зачем в базе таблица NALICHIE? В двух местах хранить одни и те же данные? Это не просто "не современно" как вы изволили выразится - это прямой путь к возникновению ошибок.
... Количество товара на складе - разница между приходом и расходом.



Уважаемый kot_,

В Вашем варианте, чтобы знать текущее наличие на "СКЛАДЕ" необходимо "калькулировать" это значение как разницу между приходами и расходами. А как быть с вопросом архивирования БД. Например, при большом товарообороте, чтобы уменьшить "нагрузку" по работе с данными, можно часть "старых по дате" записей перенести в некую архивную таблицу. Как быть в этом случае с подсчётом "приход-расход"?

А если "складов" или "магазинов" несколько?

Я понимаю, что контроль одновременной модификации количества товара
в двух таблицах ( наличие и склад/магазин) "накладнее" чем для одной, но ведь компьютеру всё равно "работать" ;)

У меня на работе программа работает в нескольких магазинах. Данные обновляю по терминалу. Там вообще не нужна бухгалтерия, т.е. "приход-расход", а наличие по магазинам - очень даже необходимо. Я понимаю, что для магазинов можно создавать такую таблицу наличия и добавлять её в пакет обновления. Но и для меня, на рабочем месте бухгалтера наличие такой "постоянной" таблицы удобно в работе. Связывается она с каталогом товара как "master-detail" через индекс, работает быстро. Как-то пробовал связать через запрос SQL - тормоза, так ради чего собственно ....

1
21 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: nikipelovav
Уважаемый kot_,

В Вашем варианте, чтобы знать текущее наличие на "СКЛАДЕ" необходимо "калькулировать" это значение как разницу между приходами и расходами. А как быть с вопросом архивирования БД. Например, при большом товарообороте, чтобы уменьшить "нагрузку" по работе с данными, можно часть "старых по дате" записей перенести в некую архивную таблицу. Как быть в этом случае с подсчётом "приход-расход"?

А если "складов" или "магазинов" несколько?


О том что это делается, я написал. Как делается - уж извините, в конце концов если вы считаете необходимым, пишите ТЗ в личку, проектирование БД - это тоже не малый объем работы и описать все детали - увольте, за бесплатно делать не могу - физически времени не хватает. Простейший вариант - использование в программе такой сущности как периоды. Т.е. коротко - документ который содержит итоговые остатки.
Вопрос о магазинах я вобще не считаю существенным - поверьте это делается гораздо проще чем в вашем варианте. Сущность магазин и склад являются одним из параметров собственно документа.

Цитата: nikipelovav

Я понимаю, что контроль одновременной модификации количества товара
в двух таблицах ( наличие и склад/магазин) "накладнее" чем для одной, но ведь компьютеру всё равно "работать" ;)


вопрос эффективности - это как я тоже писал - вопрос последний для БД. Первоочередная задача - надежность, однозначность и как правило расширяемость.

Цитата: nikipelovav


У меня на работе программа работает в нескольких магазинах. Данные обновляю по терминалу. Там вообще не нужна бухгалтерия, т.е. "приход-расход", а наличие по магазинам - очень даже необходимо. Я понимаю, что для магазинов можно создавать такую таблицу наличия и добавлять её в пакет обновления. Но и для меня, на рабочем месте бухгалтера наличие такой "постоянной" таблицы удобно в работе. Связывается она с каталогом товара как "master-detail" через индекс, работает быстро. Как-то пробовал связать через запрос SQL - тормоза, так ради чего собственно ....


мда. понятно. Собственно удобно - делайте. Это ваша работа. К сожалению времени на объяснение и примеры просто физически нет -
как в принципе что либо доказывать. Все сворачиваюсь - нет времени

305
21 ноября 2007 года
Kashuk
385 / / 21.02.2003
Цитата: oxotnik333
вот в аксессе накидал... есть таблица с товарами и есть накладная в которую забиваются записи из товаров (т.е. они связаны по ключу)
выполняем запрос и таблица (поле количество) товаров уменьшается на количество указанное в накладной:
 
Код:
UPDATE Tovar
  INNER JOIN Naklad
  ON Tovar.Id=Naklad.Id
SET Tovar.CountTov = Tovar.CountTov-Naklad.CountTov;


хы... от чего ушли, к тому и пришли :D



Это точно... :D
Тоже самое я был в начале написал :)
Суть в том, что в аксесе такой запрос работает, а в билдере (бде-квери) не хочет...

На данный момент так и реализовано, что перебираются все записи в накладной, и на это значение уменьшается количество на складе... Думал может подскажут как такой запрос реализовать что б заработало с бде. А тут началось...

Всем спасибо!
Думаю лучше закрыть это обсуждение :)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог