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 do   begin     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 do   begin     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 do   begin     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_SEL returns (     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 name with 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 ID with 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 тоже так умеют) Спасибо за информацию, попробую. Однако, всегда стараюсь обходиться минимумом сторонних компонент, чтобы не расслабляться)  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Не тронь налаженный механизм, и он тебя не подведет. Делать надо хорошо, а плохо - само получится. 
						 | 
					 
				 
			 |  
		 
	 | 
	 |