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

Откуда:
Сообщений: 142
Написал хранимую процедуру с использование курсора.
CREATE PROCEDURE [dbo].[Search_goods] @GoodsId AS INT, @number_in as int, @DocId as int output
AS
declare @cur cursor; 
set @cur=cursor for select p.DocId
from Party p
inner join Prihod h on (p.DocId=h.PrihodId) and p.VidDoc=1
left outer join rashod r on (p.DocId=r.RashodId) and p.VidDoc=2 and r.GoodsId=h.GoodsID 
inner join Warehouse w on (p.WarehouseId=w.WarehouseId)
where (h.Number -
CASE WHEN r.Number IS NULL THEN 0 ELSE r.Number END)>0
and p.GoodsId=@GoodsId
order by h.DatePrihod, h.TimePrihod

OPEN @cur
FETCH NEXT FROM @cur into @DocId
WHILE @@FETCH_STATUS = 0
BEGIN
	FETCH NEXT FROM @cur into @DocId 
   
END
close @cur;
deallocate @cur;


Результат должен быть
11
12
13

declare @DocId int
exec Search_goods 
        @GoodsId = 5,
	@number_in = 12,
	@DocId=@DocId  OUTPUT
SELECT 	@DocId


Получаю на выходе только последнюю запись, значение 13. Что не так делаю? Помогите разобраться.
7 мар 19, 21:15    [21827732]     Ответить | Цитировать Сообщить модератору
 Re: Хранимая процедура с курсором  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 27889
Андрей1985
Результат должен быть
11
12
13

declare @DocId int
exec Search_goods 
        @GoodsId = 5,
	@number_in = 12,
	@DocId=@DocId  OUTPUT
SELECT 	@DocId

Получаю на выходе только последнюю запись, значение 13. Что не так делаю? Помогите разобраться.
Переменная @DocId - это целое число. Одно целое число. Наверняка есть такие языки программирования, в который в переменную можно записать несколько чисел, но T-SQL не из таких.
7 мар 19, 22:02    [21827753]     Ответить | Цитировать Сообщить модератору
 Re: Хранимая процедура с курсором  [new]
londinium
Member

Откуда: Киев
Сообщений: 1065
Андрей1985,

Вы же пишете в скалярную переменную, надо бы в таблицу. попробуйте изобразить что-то такое:

CREATE PROCEDURE [dbo].[Search_goods] @GoodsId AS INT, @number_in as int, @DocId as int output
AS
declare @OutTable TABLE(DocID INT);
DECLARE @InTemp INT;
declare @cur cursor; 
set @cur=cursor for select p.DocId
from Party p
inner join Prihod h on (p.DocId=h.PrihodId) and p.VidDoc=1
left outer join rashod r on (p.DocId=r.RashodId) and p.VidDoc=2 and r.GoodsId=h.GoodsID 
inner join Warehouse w on (p.WarehouseId=w.WarehouseId)
where (h.Number -
CASE WHEN r.Number IS NULL THEN 0 ELSE r.Number END)>0
and p.GoodsId=@GoodsId
order by h.DatePrihod, h.TimePrihod

OPEN @cur
FETCH NEXT FROM @cur into @DocId
WHILE @@FETCH_STATUS = 0
BEGIN
	FETCH NEXT FROM @cur into @InTemp;
        INSERT @OutTable(DocID)VALUES(@InTemp);
   
END
close @cur;
deallocate @cur;
SELECT DocID FROM @OutTable;
7 мар 19, 22:04    [21827756]     Ответить | Цитировать Сообщить модератору
 Re: Хранимая процедура с курсором  [new]
Андрей1985
Member

Откуда:
Сообщений: 142
Cпасибо. Переделал через таблицу. Работает...
ALTER PROCEDURE [dbo].[Search_goods] @GoodsId AS INT, @number_in as int, @DocId as int output
AS
declare @OutTable TABLE(DocID INT);
declare @cur cursor; 
set @cur=cursor for select p.DocId
from Party p
inner join Prihod h on (p.DocId=h.PrihodId) and p.VidDoc=1
left outer join rashod r on (p.DocId=r.RashodId) and p.VidDoc=2 and r.GoodsId=h.GoodsID 
inner join Warehouse w on (p.WarehouseId=w.WarehouseId)
where (h.Number -
CASE WHEN r.Number IS NULL THEN 0 ELSE r.Number END)>0
and p.GoodsId=@GoodsId
order by h.DatePrihod, h.TimePrihod

OPEN @cur
FETCH NEXT FROM @cur into @DocId
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT @OutTable(DocID)VALUES(@DocId);
	FETCH NEXT FROM @cur into @DocId;  
END
close @cur;
deallocate @cur;
SELECT DocID FROM @OutTable;


DECLARE	@DocId int

EXEC	Search_goods
		@GoodsId = 5,
		@number_in = 12,
		@DocId = @DocId OUTPUT
GO
7 мар 19, 22:42    [21827781]     Ответить | Цитировать Сообщить модератору
 Re: Хранимая процедура с курсором  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2189
Андрей1985,
Напишите вот так и не парьте себе мозг.
CREATE PROCEDURE [dbo].[Search_goods] @GoodsId AS INT, @number_in as int
AS
select p.DocId
from Party p
inner join Prihod h on (p.DocId=h.PrihodId) and p.VidDoc=1
left outer join rashod r on (p.DocId=r.RashodId) and p.VidDoc=2 and r.GoodsId=h.GoodsID 
inner join Warehouse w on (p.WarehouseId=w.WarehouseId)
where (h.Number -
CASE WHEN r.Number IS NULL THEN 0 ELSE r.Number END)>0
and p.GoodsId=@GoodsId
order by h.DatePrihod, h.TimePrihod

Если же вам нужно потом результат использовать в другом запросе - напишите функцию вместо процедуры.
7 мар 19, 22:54    [21827785]     Ответить | Цитировать Сообщить модератору
 Re: Хранимая процедура с курсором  [new]
iap
Member

Откуда: Москва
Сообщений: 46633
Андрей1985
(h.Number -
CASE WHEN r.Number IS NULL THEN 0 ELSE r.Number END)>0
Это что за динозавр? Может, так?
h.Number>ISNULL(r.Number,0)
?
Или
(r.Number IS NULL AND h.Number>0 OR h.Number>r.Number)
?
8 мар 19, 15:56    [21828010]     Ответить | Цитировать Сообщить модератору
 Re: Хранимая процедура с курсором  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8501
Андрей1985
Cпасибо. Переделал через таблицу. Работает...
+
ALTER PROCEDURE [dbo].[Search_goods] @GoodsId AS INT, @number_in as int, @DocId as int output
AS
declare @OutTable TABLE(DocID INT);
declare @cur cursor; 
set @cur=cursor for select p.DocId
from Party p
inner join Prihod h on (p.DocId=h.PrihodId) and p.VidDoc=1
left outer join rashod r on (p.DocId=r.RashodId) and p.VidDoc=2 and r.GoodsId=h.GoodsID 
inner join Warehouse w on (p.WarehouseId=w.WarehouseId)
where (h.Number -
CASE WHEN r.Number IS NULL THEN 0 ELSE r.Number END)>0
and p.GoodsId=@GoodsId
order by h.DatePrihod, h.TimePrihod

OPEN @cur
FETCH NEXT FROM @cur into @DocId
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT @OutTable(DocID)VALUES(@DocId);
	FETCH NEXT FROM @cur into @DocId;  
END
close @cur;
deallocate @cur;
SELECT DocID FROM @OutTable;


DECLARE	@DocId int

EXEC	Search_goods
		@GoodsId = 5,
		@number_in = 12,
		@DocId = @DocId OUTPUT
GO

Что, реально работает?!

PS Используйте вариант Mind - у Вас по факту простой select с параметрами. Если логика НА САМОМ ДЕЛЕ более сложная, то да - делайте через курсор, но ДОБАВЛЯЙТЕ тогда данные в таблицу/табличную переменную,- и в конце делайте select. Вызов получившейся Вашей процедуры из TSQL:
 insert into MyTable (field1, field2,...) execute MyProc param1='dff', param2='dsfsf';
9 мар 19, 23:46    [21828579]     Ответить | Цитировать Сообщить модератору
 Re: Хранимая процедура с курсором  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 27889
SIMPLicity_
ДОБАВЛЯЙТЕ тогда данные в таблицу/табличную переменную,- и в конце делайте select.
Он же так и делает.

Использование курсора, конечно, тут выглядит комично, но, может, это такое задание от препода...
10 мар 19, 01:26    [21828599]     Ответить | Цитировать Сообщить модератору
 Re: Хранимая процедура с курсором  [new]
iap
Member

Откуда: Москва
Сообщений: 46633
Кстати, непонятно, зачем объявлять переменную типа CURSOR.
10 мар 19, 13:30    [21828687]     Ответить | Цитировать Сообщить модератору
 Re: Хранимая процедура с курсором  [new]
Диклевич Александр
Member

Откуда:
Сообщений: 601
iap
Кстати, непонятно, зачем объявлять переменную типа CURSOR.

ну например, "A cursor variable does not have to be explicitly deallocated. The variable is implicitly deallocated when it goes out of scope.", взято отсюда.
10 мар 19, 14:44    [21828701]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить