| 
			| 
					
						| NeferSky 
								Постоялец    Offline 
								Бессмертный
								
								
								
								
								
							 | 
								|  | «  : 18-06-2015 06:50 »  |  | 
 
 Доброго времени суток. Разъясните мне кто-нибудь, пожалуйста, как именно обращаться с параметрами в IBDataSet. Тут: http://www.ibase.ru/devinfo/ibx.htm  русским по белому написано, что  Вместо запросов в InsertSQL/UpdateSQL/DeleteSQL ( ... ) можно указывать вызов хранимых процедур. Именно так я и хочу делать. Суть вопроса: IDE - Delphi7. Есть этот самый датасет dsShop. У него есть InsertSQL: execute procedure shop_ins(:shop_num, :org_name, :city, :address, :merchant)
Сохраненка, которую он вызывает: create or alter procedure SHOP_INS (SHOP_NUM type of column SHOP.SHOP_NUM,
 ORG_NAME type of column SHOP.ORG_NAME,
 CITY type of column SHOP.CITY,
 ADDRESS type of column SHOP.ADDRESS,
 MERCHANT type of column SHOP.MERCHANT)
 as
 begin
 insert into shop (
 id,
 shop_num,
 org_name,
 city,
 address,
 merchant,
 active_flag)
 values (
 gen_id(shop_id, 1),
 :shop_num,
 :org_name,
 :city,
 :address,
 :merchant,
 1);
 end^
Как я это делаю сейчас: with dsShop dobegin
 Open;
 Insert;
 FieldByName('shop_num').AsString := frmShopEdit.edtShopNum.Text;
 FieldByName('org_name').AsString := frmShopEdit.edtOrgName.Text;
 FieldByName('city').AsString := frmShopEdit.edtCity.Text;
 FieldByName('address').AsString := frmShopEdit.edtAddress.Text;
 FieldByName('merchant').AsInteger := StrToInt(frmShopEdit.edtMerchant.Text);
 Post;
 Close;
 end;
 
Но, насколько я понимаю, Insert/Post - это некая "прямая" вставка, в обход сохраненки. Или нет? Исходя из статьи на ibase.ru, видимо, надо делать так: with dsShop dobegin
 Open;
 Prepare;
 ParamByName('shop_num').AsString := frmShopEdit.edtShopNum.Text;
 ParamByName('org_name').AsString := frmShopEdit.edtOrgName.Text;
 ParamByName('city').AsString := frmShopEdit.edtCity.Text;
 ParamByName('address').AsString := frmShopEdit.edtAddress.Text;
 ParamByName('merchant').AsInteger := StrToInt(frmShopEdit.edtMerchant.Text);
 Insert;
 Close;
 end;
 
но в ответ получаю, что Field "shop_num" not found. Так как, все-таки, надо передавать параметры в сохраненку? |  
						| 
								|  |  
								|  |  Записан | 
 
 Не тронь налаженный механизм, и он тебя не подведет.Делать надо хорошо, а плохо - само получится.
 |  |  | 
	| 
			| 
					
						| x77 
								Модератор
								
								   Offline 
								Пол:    
								меняю стакан шмали на обратный билет с Марса.
								
								
								
								
								
							 | 
								|  | « Ответ #1 : 18-06-2015 07:38 »  |  | 
 
 Но, насколько я понимаю, Insert/Post - это некая "прямая" вставка, в обход сохраненки. Или нет? нет. если указан InsertSQL, то он и будет вызываться. и в него будут попадать значения, которые вы передаете в поля (не в параметры) в режиме dsInsert/dsEdit. т.е. должен нормально работать ваш текущий вариант, и он должен вызывать сохраненку сам. з.ы. и не заморачивайтесь с Prepare, для статических запросов он вызовется автоматически, да и смысл он имеет только в том случае, если происходит многократный вызов одного и того же параметризованного запроса или если в рантайм надо, например, получить план выполнения запроса без отправки самого запроса на сервер. |  
						| 
								|  |  
								| « Последнее редактирование: 18-06-2015 07:41 от x77 » |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| NeferSky 
								Постоялец    Offline 
								Бессмертный
								
								
								
								
								
							 | 
								|  | « Ответ #2 : 18-06-2015 07:55 »  |  | 
 
 Гм... А для чего же тогда используются параметры? Только для методов типа ExecQuery? |  
						| 
								|  |  
								|  |  Записан | 
 
 Не тронь налаженный механизм, и он тебя не подведет.Делать надо хорошо, а плохо - само получится.
 |  |  | 
	| 
			| 
					
						| x77 
								Модератор
								
								   Offline 
								Пол:    
								меняю стакан шмали на обратный билет с Марса.
								
								
								
								
								
							 | 
								|  | « Ответ #3 : 18-06-2015 08:07 »  |  | 
 
 параметры используются не только в IBDataset. и нужны они для обращения к параметрам, а в вашем случае вам надо обращаться к полю, т.к. IBDataset - это шняга, работающая с двунаправленным набором данных. преобразования значений полей (по сути - буфера) в параметры для вызова нижележащих процедур датасет будет делать сам. |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| NeferSky 
								Постоялец    Offline 
								Бессмертный
								
								
								
								
								
							 | 
								|  | « Ответ #4 : 18-06-2015 10:24 »  |  | 
 
 Что-то я все равно не могу состыковать вызов... Аналогичный датасет dsKKM. InsertSQL: execute procedure kkm_ins(:shop_name, :kkm_num, :description)
Сохраненка: create or alter procedure KKM_INS (SHOP_NAME varchar(50),
 KKM_NUM type of column KKM.KKM_NUM,
 DESCRIPTION type of column KKM.DESCRIPTION)
 as
 begin
 insert into kkm(
 id,
 shop_id,
 kkm_num,
 description,
 active_flag)
 values (
 gen_id(kkm_id, 1),
 (select s.id from shop s
 where s.shop_num = :shop_name),
 :kkm_num,
 :description,
 1);
 end^
Вызов: with dsKKM dobegin
 Open;
 Insert;
 FieldByName('shop_name').AsString := frmKKMEdit.cbShopNum.Text;
 FieldByName('kkm_num').AsInteger := StrToInt(frmKKMEdit.edtKKMNum.Text);
 FieldByName('description').AsString := frmKKMEdit.memDescription.Text;
 Post;
 Close;
 end;
Результат: dsKKM: Field 'shop_name' not found Если датасет работает с полями - это значит, что в сохраненку ничего постороннего (не соответствующего набору полей) пихать нельзя? |  
						| 
								|  |  
								|  |  Записан | 
 
 Не тронь налаженный механизм, и он тебя не подведет.Делать надо хорошо, а плохо - само получится.
 |  |  | 
	| 
			| 
					
						| x77 
								Модератор
								
								   Offline 
								Пол:    
								меняю стакан шмали на обратный билет с Марса.
								
								
								
								
								
							 | 
								|  | « Ответ #5 : 18-06-2015 10:38 »  |  | 
 
 а в SelectSQL что? |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| x77 
								Модератор
								
								   Offline 
								Пол:    
								меняю стакан шмали на обратный билет с Марса.
								
								
								
								
								
							 | 
								|  | « Ответ #6 : 18-06-2015 10:40 »  |  | 
 
 просто чтобы параметры обрабатывались автоматически, их имена должны совпадать с именами столбцов таблицы. а для этого их надо сначала получить. |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| NeferSky 
								Постоялец    Offline 
								Бессмертный
								
								
								
								
								
							 | 
								|  | « Ответ #7 : 18-06-2015 11:02 »  |  | 
 
 SelectSQL: Сохраненка: create or alter procedure KKM_SELreturns (
 ID type of column KKM.ID,
 SHOP_ID type of column KKM.SHOP_ID,
 KKM_NUM type of column KKM.KKM_NUM,
 DESCRIPTION type of column KKM.DESCRIPTION,
 ACTIVE_FLAG type of column KKM.ACTIVE_FLAG)
 as
 begin
 for select id,
 shop_id,
 kkm_num,
 description,
 active_flag
 from kkm
 into :id,
 :shop_id,
 :kkm_num,
 :description,
 :active_flag
 do
 begin
 suspend;
 end
 end^
 
их имена должны совпадать с именами столбцов таблицы Наверное, это и будет ответом на тему... |  
						| 
								|  |  
								|  |  Записан | 
 
 Не тронь налаженный механизм, и он тебя не подведет.Делать надо хорошо, а плохо - само получится.
 |  |  | 
	| 
			| 
					
						| x77 
								Модератор
								
								   Offline 
								Пол:    
								меняю стакан шмали на обратный билет с Марса.
								
								
								
								
								
							 | 
								|  | « Ответ #8 : 18-06-2015 11:04 »  |  | 
 
 попробуйте, не получится - будем копать дальше. |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| NeferSky 
								Постоялец    Offline 
								Бессмертный
								
								
								
								
								
							 | 
								|  | « Ответ #9 : 18-06-2015 20:12 »  |  | 
 
 Попробовал, конечно, поле попереименовывать, но делу это не помогло. Похоже, лучшим решением будет дергать сохраненку IBSQL'ем с параметрами, а датасет использовать только для просмотра. У датасета все запросы - те же IBSQL, поэтому и хотелось завести все одним компонентом. Отпишусь о результатах. |  
						| 
								|  |  
								|  |  Записан | 
 
 Не тронь налаженный механизм, и он тебя не подведет.Делать надо хорошо, а плохо - само получится.
 |  |  | 
	| 
			| 
					
						| x77 
								Модератор
								
								   Offline 
								Пол:    
								меняю стакан шмали на обратный билет с Марса.
								
								
								
								
								
							 | 
								|  | « Ответ #10 : 18-06-2015 21:05 »  |  | 
 
 решайте задачу поэтапно. задайте SelectSQL, проверьте, что все работает, задайте InsertSQL, отладьте, потом - UpdateSQL. потом заверните их в процедуру.
 судя по коду выше, вы пытаетесь вставлять запись, передавая ей код справочника магазинов. этот код вы получаете по имени, которое передаете параметром.
 
 если я правильно понял, то в вашем случае имя магазина - это именно параметр, и задаваться он должен через ParamByName,а значения для вставки непосредствено в таблицу - через FieldByName.
 
 ругань происходит потому, что селект отрабатывает только по таблице с ККМ-ами, shop_name там нет. поэтоум также можно попробовать переписать селект, подтащив по джойну название магазина из справочника.
 
 но сами по себе все эти телодвижения мне кажутся лишними, и если вы сформулируете задачу, то наверное можно будет посоветовать что-то по-существу.
 |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| NeferSky 
								Постоялец    Offline 
								Бессмертный
								
								
								
								
								
							 | 
								|  | « Ответ #11 : 22-06-2015 07:12 »  |  | 
 
 В общем, исправил много недочетов в коде. 1) В БД выкинул использование доменов. (Где-то в документации по InterBase/FireBird указывалось, что домен можно редактировать, и при этом изменения коснутся всех полей и переменных, которым присвоен тип этого домена. Ни разу не получилось так сделать, только ограничения лишние накладывали) create or alter procedure KKM_INS (ID integer,
 SHOP_ID integer,
 KKM_NUM bigint,
 DESCRIPTION varchar(255),
 ACTIVE_FLAG smallint)
 as
 begin
 insert into kkm(
 id,
 shop_id,
 kkm_num,
 description,
 active_flag)
 values (
 :id,
 :shop_id,
 :kkm_num,
 :description,
 :active_flag);
 end^
 
2) В код Delphi в блоки Insert/Post Edit/Post включил все поля таблиц, с которыми работают датасеты. Соответственно, пришлось получать ID'шники из программы, и добавлять их в блоки, а не просто в БД их генерировать и присваивать. То же самое касается значений "по умолчанию". С самого начала я не добавлял в параметры сохраненки абсолютно все поля. Для инсерта, например, значения по умолчанию и ID не указывал. frmKKMEdit: // Get shop param by namewith frmMain.sqlSber do
 begin
 SQL.Text := 'select * from get_shop_by_name(:shop_name)';
 ParamByName('shop_name').AsString := cbShopName.Text;       <- Находим ID того, что выбрал пользователь
 ExecQuery;
 end;
 ShopID := frmMain.sqlSber.Fields[0].AsInteger;
 frmMain.sqlSber.Close;
 
frmMain: // Get new IDwith sqlSber do
 begin
 SQL.Text := 'select * from get_kkm_gen';
 ExecQuery;
 end;
 KKMID := sqlSber.Fields[0].AsInteger;
 sqlSber.Close;
 
 // Insert
 with dsKKM do
 begin
 Open;
 Insert;
 FieldByName('id').AsInteger := KKMID;
 FieldByName('shop_id').AsInteger := frmKKMEdit.ShopID;
 FieldByName('kkm_num').AsInteger := StrToInt(frmKKMEdit.edtKKMNum.Text);
 FieldByName('description').AsString := frmKKMEdit.memDescription.Text;
 FieldByName('active_flag').AsInteger := Integer(frmKKMEdit.cbActive.Checked);
 Post;
 Close;
 end;
 
3) Также пришлось получать в программе id-значения "выбираемых" полей из связанных таблиц.(Например, id значения, выбранного в комбобоксе). Можно, конечно, и массивы сюда прикрутить, типа локального кэша "id-value" таблицы, из которой заполняется комбобокс, но... излишество, имхо. Сначала я пытался просто передавать значение в сохраненку, чтобы БД сама находила нужный ID. execute procedure kkm_ins(:id, :shop_id, :kkm_num, :description, :active_flag)
Вот... С исправлением всего этого работает, тема закрыта. X77 благодарю за объяснение, советы и подсказки. зы: После работы над этим проектом сделаю программу-демку, в которой все-таки попробую еще раз создать сохраненку инсерта с какими попало параметрами, и вызвать ее Edit/Post'ом    А то аж за живое задело - "а я хочу так!"   |  
						| 
								|  |  
								|  |  Записан | 
 
 Не тронь налаженный механизм, и он тебя не подведет.Делать надо хорошо, а плохо - само получится.
 |  |  | 
	| 
			| 
					
						| x77 
								Модератор
								
								   Offline 
								Пол:    
								меняю стакан шмали на обратный билет с Марса.
								
								
								
								
								
							 | 
								|  | « Ответ #12 : 22-06-2015 07:19 »  |  | 
 
 посмотрите на FIBPlus. там почти такой же набор компонентов, как в IBX, но при этом они умеют делать львиную часть рутинной работы. например, каждому датасету можно сразу указать, какое поле является ключевым и значением какого генератора заполняется, и многое другое.  |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| NeferSky 
								Постоялец    Offline 
								Бессмертный
								
								
								
								
								
							 | 
								|  | « Ответ #13 :  22-06-2015 07:26 »   |  | 
 
 датасету можно сразу указать, какое поле является ключевым и значением какого генератора заполняется
 IBX тоже так умеют) Спасибо за информацию, попробую. Однако, всегда стараюсь обходиться минимумом сторонних компонент, чтобы не расслабляться) |  
						| 
								|  |  
								|  |  Записан | 
 
 Не тронь налаженный механизм, и он тебя не подведет.Делать надо хорошо, а плохо - само получится.
 |  |  | 
	|  |