Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Очень популярная тема (более 25 ответов) Помогите выполнить ХП (число прочтений - 9302 )
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Помогите выполнить ХП
21. Февраля 2007 :: 12:36
Печать  
На сервере есть база не 1С, где есть хранимая процедура p_Insert_Juridical_Perosn:
Код
Выбрать все
CREATE  Procedure [dbo].p_Insert_Juridical_Perosn
	@asABBREVIATED_NAME varchar(20) ,
	@asFIRM_NAME varchar(300),
	@asINN varchar(12),
	@asTelePhone varchar(20),
	@asCountry varchar(30),
	@asState varchar(30),
	@asCity varchar(30),
	@asStreet varchar(30),
	@asHouse_Number varchar(10),
	@asApartment_Number varchar(10),
	@asRegion varchar(30),
	@asZip varchar(10),
	@asBuilding varchar(10),
	@asNP varchar(40),
	@asRet int output
AS
DECLARE @SUBJECT_ID as bigint
SELECT @SUBJECT_ID=SUBJECT_ID
	from JURIDICAL_PERSON
	WHERE ABBREVIATED_NAME=@asABBREVIATED_NAME
	if @@ROWCOUNT=0
	begin
		set @asRet=1
		insert into SUBJECT (SUBJECT_TYPE_ID) values ('JURIDICAL_PERSON')
		set @SUBJECT_ID=@@IDENTITY
		insert into JURIDICAL_PERSON (SUBJECT_ID) values(@SUBJECT_ID)
	end
	else
	begin
		set @asRet=0
	end
		UPDATE JURIDICAL_PERSON
			set 	ABBREVIATED_NAME=@asABBREVIATED_NAME,
				FIRM_NAME=@asFIRM_NAME,
				INN=@asINN,
				POST_ADDR_EQU_JUR_ADDR=1,
				[ORG_FORM]=6
				where SUBJECT_ID=@SUBJECT_ID
			SELECT SUBJECT_ID FROM dbo.ADDRESS WHERE SUBJECT_ID=@SUBJECT_ID
			if @@ROWCOUNT=0
			begin
				insert into ADDRESS (SUBJECT_ID,ADDRESS_TYPE) values (@SUBJECT_ID,3)
			end
				UPDATE ADDRESS set		[COUNTRY]=@asCountry,
							[STATE]=@asState,
							[CITY]=@asCity,
							[STREET]=@asStreet,
							[HOUSE_NUMBER]=@asHouse_Number,
							[APARTMENT_NUMBER]=@asApartment_Number,
							[REGION]=@asRegion,
							[ZIP]=@asZip,
							[BUILDING]=@asBuilding,
							[NP]=@asNP
					where SUBJECT_ID=@SUBJECT_ID and ADDRESS_TYPE=3
			SELECT SUBJECT_ID FROM dbo.CONNECT_COORD WHERE SUBJECT_ID=@SUBJECT_ID
			if @@ROWCOUNT=0
			begin
				INSERT INTO CONNECT_COORD([SUBJECT_ID],
							[HOME_PHONE])
				VALUES(@SUBJECT_ID,
							@asTelePhone)
			end
			else
			begin
				UPDATE CONNECT_COORD set HOME_PHONE=@asTelePhone
					where SUBJECT_ID=@SUBJECT_ID
			end

GO
 



Мне очень хочется выполнить её, но что-то никак не получается. Делаю так:
Код
Выбрать все
		ОДБЦБаза.Соединение(ConnectionString);
	РСЮрЛица = СоздатьОбъект("ODBCRecordSet");
	РСЮрЛица.УстБД(ОДБЦБаза);
		РСЮрЛица.Подготовить("{call p_Insert_Juridical_Perosn (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}");

	РСЮрЛица.ДобПараметр(1,15,20,0,"@asABBREVIATED_NAME");//asABBREVIATED_NAME
	РСЮрЛица.ДобПараметр(1,15,300,0,"@asFIRM_NAME");//asFIRM_NAME
	РСЮрЛица.ДобПараметр(1,15,12,0,"@asINN");//asINN
	РСЮрЛица.ДобПараметр(1,15,20,0,"@asTelePhone");//asTelePhone
	РСЮрЛица.ДобПараметр(1,15,30,0,"@asCountry");//asCountry
	РСЮрЛица.ДобПараметр(1,15,30,0,"@asState");//asState
	РСЮрЛица.ДобПараметр(1,15,30,0,"@asCity");//asCity
	РСЮрЛица.ДобПараметр(1,15,30,0,"@asStreet");//asStreet
	РСЮрЛица.ДобПараметр(1,15,10,0,"@asHouse_Number");//asHouse_Number
	РСЮрЛица.ДобПараметр(1,15,10,0,"@asApartment_Number");//asApartment_Number
	РСЮрЛица.ДобПараметр(1,15,30,0,"@asRegion");//asRegion
	РСЮрЛица.ДобПараметр(1,15,10,0,"@asZip");//asZip
	РСЮрЛица.ДобПараметр(1,15,10,0,"@asBuilding");//asBuilding
	РСЮрЛица.ДобПараметр(1,15,40,0,"@asNP");//asNP
//------
		РСЮрЛица.УстПараметр(1,СокрЛП(ЛЕВ(Контрагент.Наименование,20)));
	РСЮрЛица.УстПараметр(2,СокрЛП(ЛЕВ(Контрагент.ПолнНаименование,300)));
	РСЮрЛица.УстПараметр(3,СокрЛП(ЛЕВ(Контрагент.ИНН,12)));
	РСЮрЛица.УстПараметр(4,СокрЛП(ЛЕВ(Контрагент.Телефоны,20)));
	РСЮрЛица.УстПараметр(5,Страна);
	РСЮрЛица.УстПараметр(6,СокрЛП(ЛЕВ(Контрагент.Регион.Наименование,30)));
	РСЮрЛица.УстПараметр(7,СокрЛП(ЛЕВ(Контрагент.Город.Наименование,30)));
	РСЮрЛица.УстПараметр(8,СокрЛП(ЛЕВ(Контрагент.Улица.ПолноеНазвание,30)));
	РСЮрЛица.УстПараметр(9,СокрЛП(ЛЕВ(Контрагент.Дом,10)));
	РСЮрЛица.УстПараметр(10,СокрЛП(ЛЕВ(Контрагент.Кв_Оф,10)));
	РСЮрЛица.УстПараметр(11,СокрЛП(ЛЕВ(Контрагент.Район.Наименование,30)));
	РСЮрЛица.УстПараметр(12,СокрЛП(ЛЕВ(Контрагент.Индекс,10)));
	РСЮрЛица.УстПараметр(13,СокрЛП(ЛЕВ(Контрагент.Корпус,10)));
	РСЮрЛица.УстПараметр(14,СокрЛП(ЛЕВ(Контрагент.НасПункт.ПолноеНазвание,40)));

[b]Рез = РСЮрЛица.Выполнить();[/b]
	Если Рез=0 Тогда
		Сообщить(РСЮрЛица.ПолучитьОписаниеОшибки());
	Иначе
		ВозвращаемоеЗначение = Число(РСЮрЛица.ПолучПараметр(15)); //чтение параметра типа OUTPUT после выполнения.
		Если ВозвращаемоеЗначение=0 Тогда
		    Сообщить("Уже юыл! ");
		Иначе
			Сообщить("Добавили!");
		КонецЕсли;
	КонецЕсли;
 



Почему-то Рез всегда = 0 , а профайлер вообще ничего не отлавливает. Ошибки тоже никакой не сообщает.
Пробывал делать так:
Код
Выбрать все
РСЮрЛица.Подготовить("EXEC p_Insert_Juridical_Perosn ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?"); 


Тоже не катит...
Подскажите, где туплю... Как правильно?
  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #1 - 21. Февраля 2007 :: 12:57
Печать  
Ну, для начала, надо бы 15-й параметр добавить  Улыбка
..тип OUTPUT поставить
  
Наверх
ICQ  
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #2 - 21. Февраля 2007 :: 13:00
Печать  
DmitrO писал(а) 21. Февраля 2007 :: 12:57:
Ну, для начала, надо бы 15-й параметр добавить  Улыбка
..тип OUTPUT поставить

Ну да, он есть, просто скопировал хреново...
Код
Выбрать все
РСЮрЛица.ДобПараметр(2,4,8,0,"@asRet");//asRet 

  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #3 - 21. Февраля 2007 :: 13:24
Печать  
фиговая процедура.. изменять ее можно?
  
Наверх
ICQ  
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #4 - 21. Февраля 2007 :: 13:30
Печать  
DmitrO писал(а) 21. Февраля 2007 :: 13:24:
фиговая процедура.. изменять ее можно?

Можно, конечно. А что фиговые процедуры не выполняются? Просто у меня ещё много подобных, но там уже больше параметров и входных и выходных.
Я вот не пойму, почему запрос даже на сервер не уходит? Если этим же рекордсетом сделать какой-нить СЕЛЕКТ, то всё нормально....
  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #5 - 21. Февраля 2007 :: 13:47
Печать  
С помощью 1с++ значения выходных параметров в такой процедуре получить невозможно.
Дело в том что она формирует результаты, которые уходят на клиента. Причем она формирует разное количество результатов разного типа в зависимости от данных входных параметров и данных в базе. (Вероятнее всего эти результаты никому не нужны.) Далее, ODBCRecordset может получать только первый результат. Далее, по спецификации ODBC, MSSQL (да и прочих), output параметры передаются и сохраняются в буфере клиента после того как получены все результаты.
Вобщем надо избавиться от результатов. Результаты бывают 2-х типов: rowcount (количество обработанных строк (insert, update, delete)) и rowset (набор данных (select)).
Возьми, выполни ее из QA, посмотри скока хламу он выдаст в результатах, который явно тебе не нужен.
Формирование результатов типа rowcount можно подавить инструкцией set nocount on (действует на scope, т.е. в данном случае на процедуру)
Формирование результатов типа rowset можно подвавить попросту их не делая или чтобы в селект листе были только установки переменных.
  
Наверх
ICQ  
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #6 - 21. Февраля 2007 :: 13:55
Печать  
Эти результаты кроме всего прочего еще и замедляют работу процедуры, т.к. их надо передавать (и получать собственно) через сеть. Судя по всему она не должна формировать никаких результатов.
Добейся этого выполняя ее в QA.
И еще, используй ВыполнитьИнструкцию.
  
Наверх
ICQ  
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #7 - 21. Февраля 2007 :: 13:55
Печать  
DmitrO писал(а) 21. Февраля 2007 :: 13:47:
С помощью 1с++ значения выходных параметров в такой процедуре получить невозможно....

Нерешительный как-то грустно стало. Просто у меня было вот так:
Код
Выбрать все
Соединение=СоздатьОбъект("ADODB.Connection");
Соединение.Open(ConnectionString);
Cmd = СоздатьОбъект("ADODB.Command");
Cmd.ActiveConnection = Соединение;
//.....
Cmd.CommandText = "p_Insert_Juridical_Perosn";  
Cmd.CommandType = 4;//хранимая процедура
prm0=Cmd.CreateParameter("asABBREVIATED_NAME", КонстантаАДО("advarchar"),ТипПараметраАДО("adParamInput"), 20, "");
Cmd.Parameters.Append( prm0 );
//.....
Cmd.Parameters(0).Value=СокрЛП(ЛЕВ(Табл.Страхователь.Наименование,20));
//.....
Cmd.Execute(); //Выполнение и получение набора данных
ВозвращаемоеЗначение = Cmd.Parameters(14).Value; //чтение параметра типа OUTPUT после выполнения.
 


Хотел подрихтовать, да видать не получится....
Там несколько подобных процедур, это самая маленькая. Хотел идти от меньшего к большему.
  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #8 - 21. Февраля 2007 :: 14:05
Печать  
Почему не получится-то?
а через АДО какой был тип источника? OLEDB провайдер, возможно он параметры передает иначе, а может быть АДО прокачивает результаты при обращении к выходным параметрам..
В любом случае при таком коде процедуры с сервера передаются лишние данные, которые нигде не используются. Это тебя не беспокоит?
Тебе помочь с изменением кода процедуры, или сам справишься?
  
Наверх
ICQ  
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #9 - 21. Февраля 2007 :: 14:14
Печать  
DmitrO писал(а) 21. Февраля 2007 :: 14:05:
Почему не получится-то?
а через АДО какой был тип источника? OLEDB провайдер, возможно он параметры передает иначе, а может быть АДО прокачивает результаты при обращении к выходным параметрам..
В любом случае при таком коде процедуры с сервера передаются лишние данные, которые нигде не используются. Это тебя не беспокоит?
Тебе помочь с изменением кода процедуры, или сам справишься?

Строка соединения вот такая была:
Код
Выбрать все
ConnectionString = "driver={SQL Server};PWD=***;UID=user;Database=EASY;Server=40-adm-comp\unicuseasy" 


А от помощи не отказался бы!  Подмигивание Может всё-таки пойму кое-какие истины и перепишу все остальные (а там вообще муть. Это мне, так сказать, в наследство осталось)
  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #10 - 21. Февраля 2007 :: 14:15
Печать  
И еще.. подозрительно то, что ни чего не предпринято для блокировки данных.. может быть рассогласование если процедуру будут выполнять несколько пользователей одновременно.
  
Наверх
ICQ  
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #11 - 21. Февраля 2007 :: 14:18
Печать  
DmitrO писал(а) 21. Февраля 2007 :: 14:15:
И еще.. подозрительно то, что ни чего не предпринято для блокировки данных.. может быть рассогласование если процедуру будут выполнять несколько пользователей одновременно.

Такой ситуации точно не будет. Это выгрузка данных из 1С в очень некрасивую программу UnicusEasy (кто видел - тот знает что это), которая делается 1 раз в неделю одним пользователем (мной) больше никто в этой базе не работает.
  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #12 - 21. Февраля 2007 :: 14:40
Печать  
Ну тогда держи:
Код
Выбрать все
CREATE  Procedure [dbo].p_Insert_Juridical_Perosn
	@asABBREVIATED_NAME varchar(20) ,
	@asFIRM_NAME varchar(300),
	@asINN varchar(12),
	@asTelePhone varchar(20),
	@asCountry varchar(30),
	@asState varchar(30),
	@asCity varchar(30),
	@asStreet varchar(30),
	@asHouse_Number varchar(10),
	@asApartment_Number varchar(10),
	@asRegion varchar(30),
	@asZip varchar(10),
	@asBuilding varchar(10),
	@asNP varchar(40),
	@asRet int output
AS
set nocount on
DECLARE @SUBJECT_ID as bigint
SELECT @SUBJECT_ID=SUBJECT_ID
	from JURIDICAL_PERSON
	WHERE ABBREVIATED_NAME=@asABBREVIATED_NAME
	if @@ROWCOUNT=0
	begin
		set @asRet=1
		insert into SUBJECT (SUBJECT_TYPE_ID) values ('JURIDICAL_PERSON')
		set @SUBJECT_ID=@@IDENTITY
		insert into JURIDICAL_PERSON (SUBJECT_ID) values(@SUBJECT_ID)
	end
	else
	begin
		set @asRet=0
	end
		UPDATE JURIDICAL_PERSON
			set 	ABBREVIATED_NAME=@asABBREVIATED_NAME,
				FIRM_NAME=@asFIRM_NAME,
				INN=@asINN,
				POST_ADDR_EQU_JUR_ADDR=1,
				[ORG_FORM]=6
				where SUBJECT_ID=@SUBJECT_ID

			UPDATE ADDRESS set
				[COUNTRY]=@asCountry,
				[STATE]=@asState,
				[CITY]=@asCity,
				[STREET]=@asStreet,
				[HOUSE_NUMBER]=@asHouse_Number,
				[APARTMENT_NUMBER]=@asApartment_Number,
				[REGION]=@asRegion,
				[ZIP]=@asZip,
				[BUILDING]=@asBuilding,
				[NP]=@asNP
			where SUBJECT_ID=@SUBJECT_ID and ADDRESS_TYPE=3
			if @@ROWCOUNT=0
				insert into ADDRESS (SUBJECT_ID,ADDRESS_TYPE,
					COUNTRY,
					STATE,
					CITY,
					STREET,
					HOUSE_NUMBER,
					APARTMENT_NUMBER,
					REGION,
					ZIP,
					BUILDING,
					NP)
				values (@SUBJECT_ID,3,
					@asCountry,
					@asState,
					@asCity,
					@asStreet,
					@asHouse_Number,
					@asApartment_Number,
					@asRegion,
					@asZip,
					@asBuilding,
					@asNP)

			UPDATE CONNECT_COORD
				set HOME_PHONE=@asTelePhone
			where SUBJECT_ID=@SUBJECT_ID
			if @@ROWCOUNT=0
				INSERT INTO CONNECT_COORD([SUBJECT_ID], [HOME_PHONE]) VALUES(@SUBJECT_ID, @asTelePhone)

GO 


основной прием: обычно делают сразу update (без предварительного select), если нет измененной записи, тогда делают insert.
(обычно правда это еще в одну транзакцию ставят и при update ставится holdlock, т.к. между ними всеже может проскочить какой-нить самый пессимистический зараза-юзер Улыбка)
  
Наверх
ICQ  
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #13 - 21. Февраля 2007 :: 14:54
Печать  
Спасибо.
Но, я так понимаю, придётся остаться на объектах "ADODB.Command" и "ADODB.Connection"?
А такая вот модификация запроса разве сильный прирост даст?
  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Помогите выполнить ХП
Ответ #14 - 21. Февраля 2007 :: 17:25
Печать  
Не правильно понимаешь.
Такая процедура должна работать через ODBCRecordset.
Эта модификация не даст сильного прироста производительности.
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать