Функция возвращающая таблицу -- Переменные внутри?

rtyts
Дата: 14.01.2009 16:59:54
Првт всем. Столкнулся с использованием Table-Valued Functions. Правильно ли я понял, что внутри функции нельзя объявлять переменные то есть:
CREATE FUNCTION [dbo].[tmp_fnc_sel] 
(@P int, @DT datetime)
RETURNS TABLE 
AS
BEGIN
DECLARE @dd AS int
DECLARE @mm As int
DECLARE @yy AS int

SET @dd=DATEPART(dd,@DT)
SET @mm=DATEPART(mm,@DT)
SET @yy=DATEPART(yy,@DT)

RETURN 
(
SELECT [P]
      ,[Mark]
      ,[АЕ]
      FROM [DB_].[dbo].[tbl_В] 
WHERE P=@P AND @dd=day_
                                 AND @mm=month_
                                     AND @yy=year_
)
END
Невыполнимо, а делать надо только так

CREATE FUNCTION dbo.fnc_s
(	
	@P int, @DT datetime
)
RETURNS TABLE 
AS
RETURN 
(


SELECT [P]
      ,[Mark]
      ,[АЕ]
      FROM [DB_].[dbo].[tbl_В] 
WHERE P=@P AND DATEPART(dd,@DT)=day_
                                 AND DATEPART(mm,@DT)=month_
                                     AND DATEPART(yy,@DT)=year_
)
GO

Или у меня в первом варианте синтакс неверен?
Glory
Дата: 14.01.2009 17:01:28
rtyts


Или у меня в первом варианте синтакс неверен?

Совершенно неверен
rtyts
Дата: 14.01.2009 17:05:27
автор
Правильно ли я понял, что внутри функции нельзя объявлять переменные

А тут какой ответ?
pkarklin
Дата: 14.01.2009 17:06:59
rtyts
Или у меня в первом варианте синтакс неверен?


Угу. Он отличается для Inline и Multistatement Table-Valued Functions.
Glory
Дата: 14.01.2009 17:07:40
rtyts
автор
Правильно ли я понял, что внутри функции нельзя объявлять переменные

А тут какой ответ?

Внутри функции объявлять и использовать переменные можно.
Для этого в хелпе приведено достатоточно примеров.
pkarklin
Дата: 14.01.2009 17:08:21
rtyts
автор
Правильно ли я понял, что внутри функции нельзя объявлять переменные

А тут какой ответ?


Inline функция может содержать всего лишь одну инструкцию SELECT/ Зачем в первом случае переменные - непонятно.
rtyts
Дата: 14.01.2009 17:14:03
Glory
Для этого в хелпе приведено достатоточно примеров.

Фик там!
BOL
А. Применение скалярной пользовательской функции, вычисляющей неделю по ISOUSE AdventureWorks;
GO
IF OBJECT_ID (N'dbo.ISOweek', N'FN') IS NOT NULL
DROP FUNCTION dbo.ISOweek;
GO
CREATE FUNCTION dbo.ISOweek (@DATE datetime)
RETURNS int
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE @ISOweek int;
SET @ISOweek= DATEPART(wk,@DATE)+1
-DATEPART(wk,CAST(DATEPART(yy,@DATE) as CHAR(4))+'0104');
--Special cases: Jan 1-3 may belong to the previous year
IF (@ISOweek=0)
SET @ISOweek=dbo.ISOweek(CAST(DATEPART(yy,@DATE)-1
AS CHAR(4))+'12'+ CAST(24+DATEPART(DAY,@DATE) AS CHAR(2)))+1;
--Special case: Dec 29-31 may belong to the next year
IF ((DATEPART(mm,@DATE)=12) AND
((DATEPART(dd,@DATE)-DATEPART(dw,@DATE))>= 28))
SET @ISOweek=1;
RETURN(@ISOweek);
END;
GO
SET DATEFIRST 1;
SELECT dbo.ISOweek(CONVERT(DATETIME,'12/26/2004',101)) AS 'ISO Week';
Тут да, но это ведь Scalar
А тут
BOL
Создание функции, возвращающей табличное значение, из нескольких инструкций
USE AdventureWorks;
GO
IF OBJECT_ID (N'dbo.ufn_FindReports', N'TF') IS NOT NULL
DROP FUNCTION dbo.ufn_FindReports;
GO
CREATE FUNCTION dbo.ufn_FindReports (@InEmpID INTEGER)
RETURNS @retFindReports TABLE
(
EmployeeID int primary key NOT NULL,
Name nvarchar(255) NOT NULL,
Title nvarchar(50) NOT NULL,
EmployeeLevel int NOT NULL,
Sort nvarchar (255) NOT NULL
)
--Returns a result set that lists all the employees who report to the
--specific employee directly or indirectly.*/
AS
BEGIN
WITH DirectReports(Name, Title, EmployeeID, EmployeeLevel, Sort) AS
(SELECT CONVERT(Varchar(255), c.FirstName + ' ' + c.LastName),
e.Title,
e.EmployeeID,
1,
CONVERT(Varchar(255), c.FirstName + ' ' + c.LastName)
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.EmployeeID = @InEmpID
UNION ALL
SELECT CONVERT(Varchar(255), REPLICATE ('| ' , EmployeeLevel) +
c.FirstName + ' ' + c.LastName),
e.Title,
e.EmployeeID,
EmployeeLevel + 1,
CONVERT (Varchar(255), RTRIM(Sort) + '| ' + FirstName + ' ' +
LastName)
FROM HumanResources.Employee as e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID
)
-- copy the required columns to the result of the function
INSERT @retFindReports
SELECT EmployeeID, Name, Title, EmployeeLevel, Sort
FROM DirectReports
RETURN
END;
GO
-- Example invocation
SELECT EmployeeID, Name, Title, EmployeeLevel
FROM dbo.ufn_FindReports(109)
ORDER BY Sort;
GO

Вы этот пример имеете ввиду, Glory, если да, то данный пример мне не подходит!
pkarklin
Дата: 14.01.2009 17:17:37
Имелся ввиду пример:

CREATE FUNCTION [dbo].[tmp_fnc_sel] 
(@P int, @DT datetime)
RETURNS TABLE 
AS
RETURN 
(
SELECT [P]
      ,[Mark]
      ,[АЕ]
      FROM [DB_].[dbo].[tbl_В] 
WHERE P=@P AND DATEPART(dd,@DT) = day_
                               AND DATEPART(mm,@DT)=month_
                                     AND DATEPART(yy,@DT)=year_
)
rtyts
Дата: 14.01.2009 17:19:30
pkarklin
Inline функция может содержать всего лишь одну инструкцию

У меня оба примера Table-Valued Functions. Второй работает корошо.
pkarklin
Зачем в первом случае переменные - непонятно.
Для обеспечения схожести кодов с тем, кто все делал ХП-шками.
Glory
Дата: 14.01.2009 17:22:43
rtyts
Вы этот пример имеете ввиду, Glory, если да, то данный пример мне не подходит!

Конечно. Вам подходят по всей видимости только готовые скрипты для ваших задач