Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Хранимые процедуры - контроль синтаксиса  [new]
Alex Zhulin
Member

Откуда:
Сообщений: 56
Добрый день!

Создаю процедуру типа:

ALTER PROCEDURE [dbo].[bills_supp_main]
(
	@active_from date
	, @active_to date
)
WITH EXECUTE AS 'dbo'
AS
BEGIN
	begin try
		begin transaction
		-- Создадим и откроем курсор для обхода активных точек подключения
		-- в выбранном периоде выставления счетов
		declare @terminal_resource_id int
		declare @addendum_id int
		declare @pp_active_from date
		declare @pp_active_to date;
		declare pp_cur cursor for 
		select terminal_resource_id
				, addendum_id
				, active_from
				, ISNULL(active_to, @active_to) active_to
		from pes_point_plugins
		where active_from < @active_to
			  and ISNULL(DateAdd(day, 1, active_to), active_to) > @active_from

		open pp_cur
		fetch next from cur into @terminal_resource_id, @addendum_id, @pp_active_from, @pp_active_to
		while (@@FETCH_STATUS = 0)
		begin
			print(@terminal_resource_id)
			fetch next from pp_cur into @terminal_resource_id, @addendum_id, @pp_active_from, @pp_active_to
		end
		-- Закроем и освободим курор
		close pp_cur
		deallocate pp_cur
		commit transaction
	end try
	begin catch
		if @@TRANCOUNT > 0
			ROLLBACK TRAN --RollBack in case of Error
		
		DECLARE @ErrorMessage NVARCHAR(4000);
		DECLARE @ErrorSeverity INT;
		DECLARE @ErrorState INT;
		--
		SELECT 
			@ErrorMessage = ERROR_MESSAGE(),
			@ErrorSeverity = ERROR_SEVERITY(),
			@ErrorState = ERROR_STATE();
		--
		RAISERROR (@ErrorMessage, -- Message text.
				   @ErrorSeverity, -- Severity.
				   @ErrorState -- State.
				   );
	end catch
END


В строке
fetch next from cur into @terminal_resource_id, @addendum_id, @pp_active_from, @pp_active_to
забыл заменить cur на pp_cur.
Казалось бы, что при компиляции должен получить ошибку типа "Переменная не определена".
Но нет - при компиляции получаю
Выполнение команд успешно завершено.

При исполнении получаю ошибку
Сообщение 50000, уровень 16, состояние 1, процедура bills_supp_main, строка 52
Курсор с именем "cur" не существует.


Есть ли возможность заставить компилятор хранимых процедур отлавливать такие ошибки на этапе компиляции, а не исполнения?
15 ноя 13, 08:44    [15133196]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31978
Alex Zhulin
Есть ли возможность заставить компилятор хранимых процедур отлавливать такие ошибки на этапе компиляции, а не исполнения?
Нет, ведь курсор могут и создать в момент выполнения, это же не локальная переменная.
Когда есть возможность проверить, сервер проверяет.
15 ноя 13, 09:01    [15133257]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
варнинг
Guest
alexeyvg
Alex Zhulin
Есть ли возможность заставить компилятор хранимых процедур отлавливать такие ошибки на этапе компиляции, а не исполнения?
Нет, ведь курсор могут и создать в момент выполнения, это же не локальная переменная.
Когда есть возможность проверить, сервер проверяет.


все так, но варнинг (на этапе компиляции) могли бы и приделать.
при разработке в VS, кстати, такие варнинги есть, очень помогает находить ошибки.
15 ноя 13, 09:24    [15133425]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
Alex Zhulin
Member

Откуда:
Сообщений: 56
[/quot]Нет, ведь курсор могут и создать в момент выполнения, это же не локальная переменная.
Когда есть возможность проверить, сервер проверяет.[/quot]

В части MS SQL у меня немного опыта.
Правильно ли я понимаю, что конструкция типа

declare pp_cur cursor for 
		select terminal_resource_id
				, addendum_id
				, active_from
				, ISNULL(active_to, @active_to) active_to
		from pes_point_plugins


Не объявляет переменную типа "курсор", которая "живет" в пределах процедуры, а создает некий объект сессии, для которого если не вызвать

deallocate pp_cur


То можно будет использовать в других процедурах?
15 ноя 13, 09:26    [15133441]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Alex Zhulin,

курсоры бывают глобальные и локальные.
http://msdn.microsoft.com/ru-ru/library/ms180169(v=sql.100).aspx

Не понимаю, зачем Вам курсор.
По-моему, это последнее, что должен изучать программист,
который сообщает: "В части MS SQL у меня немного опыта".
15 ноя 13, 10:02    [15133625]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
Alex Zhulin,

Если область видимости курсора не указана явно, то применяется значение опции БД CURSOR_DEFAULT.
15 ноя 13, 10:05    [15133644]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
ZOOKABAKODER
Member

Откуда:
Сообщений: 178
iap
Не понимаю, зачем Вам курсор.
По-моему, это последнее, что должен изучать программист,
который сообщает: "В части MS SQL у меня немного опыта".

С программерами часто такое, особенно в начале. Они привыкли работать с коллекциями поэлементно, поэтому всегда стараются курсором бежать.
15 ноя 13, 10:09    [15133679]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
Glory
Member

Откуда:
Сообщений: 104751
Alex Zhulin
Казалось бы, что при компиляции должен получить ошибку типа "Переменная не определена".
Но нет - при компиляции получаю
Выполнение команд успешно завершено.

Дело в том, что вы не объявляли никакой переменной. Поэтому для компилятора cur является идентификатором какого-то внешнего объекта

create procedure dbo.test1
as
begin
	declare @mycursor cursor, @x int
    SET @mycursor = CURSOR
    FORWARD_ONLY STATIC FOR
      SELECT id  FROM sys.objects;
    
	OPEN @mycursor;
	FETCH NEXT FROM @mycursorXXX INTO @x
end
15 ноя 13, 10:24    [15133795]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31978
Alex Zhulin
Не объявляет переменную типа "курсор", которая "живет" в пределах процедуры, а создает некий объект сессии, для которого если не вызвать
Да, если курсор не локальный
Glory
Дело в том, что вы не объявляли никакой переменной
Ага, нужно приучить себя всегда использовать переменные для курсоров (потому что объявить курсор в приложении, а потом использовать его в хранимых процедурах - это совсем экзотика, это пришло из унаследованного кода для совместимости)
15 ноя 13, 10:33    [15133873]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
ZOOKABAKODER
Member

Откуда:
Сообщений: 178
alexeyvg
Ага, нужно приучить себя всегда использовать переменные для курсоров (потому что объявить курсор в приложении, а потом использовать его в хранимых процедурах - это совсем экзотика, это пришло из унаследованного кода для совместимости)

Нужно приучать себя не использовать курсоры, без крайней необходимости. :)
15 ноя 13, 10:41    [15133925]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
Alex Zhulin
Member

Откуда:
Сообщений: 56
Glory
Дело в том, что вы не объявляли никакой переменной. Поэтому для компилятора cur является идентификатором какого-то внешнего объекта


Спасибо большое.
Понял.
15 ноя 13, 10:57    [15134011]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
Jaffar
Member

Откуда:
Сообщений: 633
ZOOKABAKODER
iap
Не понимаю, зачем Вам курсор.
По-моему, это последнее, что должен изучать программист,
который сообщает: "В части MS SQL у меня немного опыта".

С программерами часто такое, особенно в начале. Они привыкли работать с коллекциями поэлементно, поэтому всегда стараются курсором бежать.


видел я такой копрокод.
Там 2 таблицы джойнились с помощью 2 курсоров.
Сначала бежим по первой таблице и заносим значения всех полей в переменные,
потом во втором вложенном цикле бежим по второй таблице и тоже заносим значения всех полей в переменные,
потом делаем

IF(@TABLE1_ID = @TABLE2_IDREF) - 


то делается вставка переменных в третью таблицу.

Хорошо что таблиц было только 2.
Суровые Челябинские программисты.
15 ноя 13, 11:12    [15134132]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Alex Zhulin
Glory
Дело в том, что вы не объявляли никакой переменной. Поэтому для компилятора cur является идентификатором какого-то внешнего объекта


Спасибо большое.
Понял.


чтобы проверить что процедура правильно отработает: нужно закоментить её "шапку" и объявив переменные - выполнить ее тело.
Ну и хотя бы разок вызвать процедуру на исполнение.

--create procedure sp_PROC(@ID int, @D datetime)
--AS

declare @ID int, @D datetime
set @ID = 1
set @D  = '2013-05-20'

BEGIN
/*
 ... что-то делается.
*/
END


Кстати это не только с курсорами но и с таблицами, видами и другими объектами, так что будьте осторожнее,
не испачкайтесь .
15 ноя 13, 11:16    [15134170]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
Alex Zhulin
Member

Откуда:
Сообщений: 56
Кстати это не только с курсорами но и с таблицами, видами и другими объектами, так что будьте осторожнее,
не испачкайтесь .


Уже сталкивался
После Oracle это просто шок :-)
15 ноя 13, 13:43    [15135751]     Ответить | Цитировать Сообщить модератору
 Re: Хранимые процедуры - контроль синтаксиса  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Alex Zhulin
Кстати это не только с курсорами но и с таблицами, видами и другими объектами, так что будьте осторожнее,
не испачкайтесь .


Уже сталкивался
После Oracle это просто шок :-)


а у меня на оборот., привыкаю.
15 ноя 13, 13:49    [15135802]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить