Ahmad_kelany Ответов: 1

Как использовать, если существует в пользовательской функции, которая возвращает таблицу?


Всем привет

У меня есть запрос, который выполняется нормально:

if Exists (select top(1) invd.UnitCost from InvoiceDetails invd join Invoices inv
on invd.InvoiceID = inv.InvoiceID 
where inv.InvoiceTypeID = 3 and invd.ItemID = 212 and invd.ExpireDate ='20190430' and
upper(invd.batch) = upper('vatg') and inv.InvoiceDate <= '20170101'
order by inv.InvoiceDate desc)
select top(1) invd.UnitCost from InvoiceDetails invd join Invoices inv
on invd.InvoiceID = inv.InvoiceID 
where inv.InvoiceTypeID = 3 and invd.ItemID = 212 and invd.ExpireDate = '20190430' and
upper(invd.batch) = upper('vatg') and inv.InvoiceDate <= '20170101'
order by inv.InvoiceDate desc
Else
Select UnitCost From dbo.GetLastUnitCost(212,'20190430','vatg')


Я попытался превратить его в UDF, который возвращает таблицу, чтобы позже использовать ее с cross apply:

create Function [dbo].[GetLastUnitCostBeforeDate2](@ItemID int , @ExpDate date , @Batch nvarchar(20) ,@InvoiceDate datetime )
returns table
as
return
(

if Exists (select top(1) invd.UnitCost from InvoiceDetails invd join Invoices inv
on invd.InvoiceID = inv.InvoiceID 
where inv.InvoiceTypeID = 3 and invd.ItemID = @ItemID and invd.ExpireDate = @ExpDate and
upper(invd.batch) = upper(@Batch) and inv.InvoiceDate <= @invoiceDate
order by inv.InvoiceDate desc)
select top(1) invd.UnitCost from InvoiceDetails invd join Invoices inv
on invd.InvoiceID = inv.InvoiceID 
where inv.InvoiceTypeID = 3 and invd.ItemID = @ItemID and invd.ExpireDate = @ExpDate and
upper(invd.batch) = upper(@Batch) and inv.InvoiceDate <= @invoiceDate
order by inv.InvoiceDate desc
Else
Select UnitCost From dbo.GetLastUnitCost(@ItemId,@ExpDate,@Batch)

);


Но я получаю следующую ошибку:

Msg 156, Level 15, State 1, Procedure GetLastUnitCostBeforeDate2, Line 8 [Batch Start Line 7]
Incorrect syntax near the keyword 'if'.
Msg 102, Level 15, State 1, Procedure GetLastUnitCostBeforeDate2, Line 21 [Batch Start Line 7]
Incorrect syntax near ')'.


Что я уже пробовал:

Гуглить,
Я нашел это:
SQL-запрос возвращает значение в поле, если результаты не найдены..[^]

и многим это нравится, но я не могу найти, Как включить его в UDF, или что я упускаю

1 Ответов

Рейтинг:
11

CHill60

Вы не можете использовать if подобным образом, потому что определение схемы для UDF не обязательно уникально. Но вы можете сделать что-то вроде следующего:

create Function [dbo].[GetLastUnitCostBeforeDate2](@ItemID int , @ExpDate date , @Batch nvarchar(20) ,@InvoiceDate datetime )
returns @result table (res decimal (15,2))
as
begin
	if Exists (select top(1) invd.UnitCost 
		from InvoiceDetails invd 
		join Invoices inv on invd.InvoiceID = inv.InvoiceID 
		where inv.InvoiceTypeID = 3 and invd.ItemID = @ItemID 
			and invd.ExpireDate = @ExpDate 
			and upper(invd.batch) = upper(@Batch) and inv.InvoiceDate <= @invoiceDate
		order by inv.InvoiceDate desc)

			insert into @result 
			select top(1) invd.UnitCost from InvoiceDetails invd 
				join Invoices inv on invd.InvoiceID = inv.InvoiceID 
				where inv.InvoiceTypeID = 3 and invd.ItemID = @ItemID and invd.ExpireDate = @ExpDate and
				upper(invd.batch) = upper(@Batch) and inv.InvoiceDate <= @invoiceDate
				order by inv.InvoiceDate desc
	Else
		insert into @result Select UnitCost From dbo.GetLastUnitCost(@ItemId,@ExpDate,@Batch)
	return;
end
Основные отличия заключаются в том, что
- Я называю и определяю таблицу, которая будет возвращена
- Я вставляю результаты Select(ов) в возвращаемую таблицу, а не просто запускаю select
- Я должен использовать начальную-конечную пару, а не скобки ( )
- следите за тем, чтобы return


Ahmad_kelany

Большое спасибо.