Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Try catch и Связанная инструкция не подготовлена (число прочтений - 4996 )
Kateryne
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 76
Зарегистрирован: 30. Марта 2010
Пол: Женский
Try catch и Связанная инструкция не подготовлена
30. Марта 2010 :: 13:12
Печать  
Здравствуйте!
Стоит 2005 MS Server. Пытаюсь сделать такое:
Код
Выбрать все
пер_ТекстЗапроса = "
		|DECLARE
		|	@Err_Num int
		|    , @Err_Sever int
		|    , @Err_State int
		|    , @Err_Msg varchar(1000)
		|BEGIN
		|    BEGIN TRY
		|	  DROP DATABASE ["+СокрЛП(рф_ИмяБазыРезультатовОбзвона)+"];
		|    END TRY
		|    BEGIN CATCH
		|	  SET @Err_Num = Error_Number();
		|	  IF @Err_Num <> 3701 -- База не существует
		|	  BEGIN
		|		SET @Err_Msg = 'Код ошибки ' + Cast(@Err_Num as varchar) + ' - ' + Error_Message();
		|		SET @Err_Sever = Error_Severity();
		|		SET @Err_State = Error_State();
		|		RAISERROR(@Err_Msg, @Err_Sever, @Err_State);
		|	  END
		|    END CATCH
		|END
		|";
		пар_ODBCRecordSet.ВыполнитьСкалярный(пер_ТекстЗапроса);    



Т.е. удаляю базу. Если ее и так нет, то не ругаюсь. Если она есть, удаляю. Если при удалении возникли проблемы - вывожу ошибку.

При отсутствии базы и ее нормальном удалении - код работает. Однако, если база заблокирована, т.е. возникает перехваченное исключение, получаю ошибку:
Код
Выбрать все
State HY007, native 0, message [Microsoft][ODBC SQL Server Driver]Связанная инструкция не подготовлена 



Может ли быть дело в том, что try catch - конструкции из 2005-го сервера, и библиотека с ней не работает? Или причина в чем-то другом?
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Try catch и Связанная инструкция не подготовлена
Ответ #1 - 30. Марта 2010 :: 13:32
Печать  
Описание ошибки нужно получать из рекордсета ПолучитьОписаниеОшибки().
Код
Выбрать все
Попытка
  пар_ODBCRecordSet.ВыполнитьСкалярный(пер_ТекстЗапроса);
Исключение
  Сообщить(пар_ODBCRecordSet.ПолучитьОписаниеОшибки());
КонецПопытки;
 



Имхо, так лучше
Код
Выбрать все
	RS = СоздатьОбъект("ODBCRecordSet");
	RS.УстБД1С();

	ТекстЗапроса = "
	|if db_id('blabla') is not null
    |  drop database blabla";


	рез = RS.Выполнить(ТекстЗапроса);

	Если рез = 0 Тогда
		Сообщить(RS.ПолучитьОписаниеОшибки());
	КонецЕсли;
 

  
Наверх
 
IP записан
 
Kateryne
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 76
Зарегистрирован: 30. Марта 2010
Пол: Женский
Re: Try catch и Связанная инструкция не подготовлена
Ответ #2 - 30. Марта 2010 :: 14:59
Печать  
О, спасибо, так действительно гораздо лучше. Беда в том, что мыслю калькой с оракла, а так отлов эксепшена при попытке удаления типовой ход... про такой как у вас трюк не знала Улыбка
  
Наверх
 
IP записан
 
Kateryne
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 76
Зарегистрирован: 30. Марта 2010
Пол: Женский
Re: Try catch и Связанная инструкция не подготовлена
Ответ #3 - 01. Апреля 2010 :: 09:54
Печать  
Сделала по вашему совету, но, как выяснилось, полностью проблему это не решило.
Если оборачиваешь запрос уже в 1С:

Попытка

Исключение

КонецПопытки


Чтобы обработать ситуацию, на случай, если удаляемая база заблокирована

Соответственно, когда доходит до исключения при заблокированной базе, ругается на ту же ошибку Связанная инструкция не подготовлена
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Try catch и Связанная инструкция не подготовлена
Ответ #4 - 01. Апреля 2010 :: 10:02
Печать  
Чтобы удалить базу нужно все процессы кто в базе( см sp_who ) удалить kill <SPID>

А может будет достаточно в той базе обнулить таблицы ?
(операция по удалению базы очень серьезная задача с точки зрения пользователя
и очень дорогостоящая с точки зрения ms sql )
Или опишите Вашу задачу более  подробней.
  
Наверх
 
IP записан
 
Kateryne
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 76
Зарегистрирован: 30. Марта 2010
Пол: Женский
Re: Try catch и Связанная инструкция не подготовлена
Ответ #5 - 01. Апреля 2010 :: 10:36
Печать  
Не, я понимаю, что если база заблокирована, то она не удалится

Собственно, это и требуется:

Попытка
   sql-код удаления базы
Исключение
     Сообщить(Переменная_ODBCRecordSet.ПолучитьОписаниеОшибки())
  Устанавливаем переменную БазаНеУдалена - для дальнейшей обработки в последующем коде
КонецПопытки

Проблема в том, что вместо текста сообщения об ошибке "База заблокирована" выдается текст "Связанная инструкция не подготовлена", т.е. неинформативное сообщение. Выдавать всегда ошибку "База заблокирована" неверно, так как природа ошибки может быть и другая
  
Наверх
 
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Try catch и Связанная инструкция не подготовлена
Ответ #6 - 01. Апреля 2010 :: 19:47
Печать  
Попробуй поставить в начале запроса на удаление базы "SET NOCOUNT ON"
  
Наверх
ICQ  
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Try catch и Связанная инструкция не подготовлена
Ответ #7 - 02. Апреля 2010 :: 05:26
Печать  
А может все через хранимую процедуру сделать
(текст не отлаживал)
Код
Выбрать все
Create procedure  dbo.my_del_bd( @db_name varchar(200) )
AS

SET NOCOUNT ON

DECLARE
@Err_Num int, @Err_Sever int, @Err_State int
DECLARE @Err_Msg varchar(1000)
BEGIN
	BEGIN TRY
		IF db_id(@db_name) is  null
		BEGIN
			select 'BASE NOT FOUND'
			return
		END

		DROP DATABASE @db_name
		select 'Ok'
		return
	END TRY
	BEGIN CATCH
	  SET @Err_Num = Error_Number()
		SET @Err_Msg = 'Код ошибки ' + Cast(@Err_Num as varchar) + ' - ' + Error_Message()
		select @Err_Msg
		return
		-- что делают эти три оператора точно не знаю
		SET @Err_Sever = Error_Severity()
		SET @Err_State = Error_State()
		RAISERROR(@Err_Msg, @Err_Sever, @Err_State)
	   END CATCH
END
 



Вызов из 1с

Код
Выбрать все
ТЗ = пар_ODBCRecordSet.ВыполнитьИнструкцию("EXEC dbo.my_del_bd 'konkretnoe_name_db'");  
ТЗ.ВыбратьСтроку();
 

« Последняя редакция: 02. Апреля 2010 :: 14:59 - Z1 »  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Try catch и Связанная инструкция не подготовлена
Ответ #8 - 02. Апреля 2010 :: 08:39
Печать  
тоже не понимаю, честно говоря. По-идее, если база занята, Выполнить() с этим запросом:
Код
Выбрать все
ТекстЗапроса = "
|if db_id('dbname') is not null
|  drop database dbname";
 


должен возвращать 0. Возвращает 1.фз Озадачен
Работает, более менее как ожидается, если в тексте запроса одна инструкция, например:
Код
Выбрать все
	RS = СоздатьОбъект("ODBCRecordSet");
	RS.УстБД1С();

	рез = RS.Выполнить("drop database dbname");

	Если рез = 0 Тогда
		Сообщить(RS.ПолучитьОписаниеОшибки());
	КонецЕсли;
 


Можно искать в тексте ошибки текст "3701," Нерешительный
  
Наверх
 
IP записан
 
Kateryne
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 76
Зарегистрирован: 30. Марта 2010
Пол: Женский
Re: Try catch и Связанная инструкция не подготовлена
Ответ #9 - 02. Апреля 2010 :: 14:29
Печать  
ок, видимо переделаю на однострочный запрос.
всем спасибо Улыбка
  
Наверх
 
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Try catch и Связанная инструкция не подготовлена
Ответ #10 - 03. Апреля 2010 :: 05:29
Печать  
Попытаюсь еще раз порекомендовать "SET NOCOUNT ON"
http://connect.microsoft.com/VisualStudio/feedback/details/95095/odbc-client-get...
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать