我可以调用未通过存储过程定义的函数吗?
考虑一下我们的存储过程如下:
CREATE PROCEDURE [dbo].[stp__getClients]
AS
BEGIN
SET NOCOUNT ON;
Select Id,Name,Status ,
(CASE WHEN Status = 3 then run_date_calc(FromDate , ToDate) else ''
end) as DateRangeDesc
From ClientsTbl
...
END
GO
我想在Select
添加另一个属性:
(CASE WHEN Status = 3 then run_date_calc(FromDate , ToDate) else '' end)
我们想在SP内部创建一个名为run_date_calc
的函数
将得到两个日期并返回一个包含其范围描述的字符串
看起来像:
declare @d1 datetime, @d2 datetime, @year int, @month int, @d int
set @d1 = '2009-09-24'
set @d2 = '2012-04-23'
set @year = datediff(year, @d1, @d2) - 1
set @month = datediff(month, dateadd(year, @year, @d1), @d2)
if dateadd(month, @month, dateadd(year, @year, @d1)) > @d2 set @month = @month - 1
set @d = datediff(day, dateadd(month, @month, dateadd(year, @year, @d1)), @d2)
print cast(@year as nvarchar) + ' year(s) ' + cast(@month as nvarchar) + ' month(s) and ' + cast(@d as nvarchar) + ' day(s)'
是否可以制作一个"内部功能"并在SP内部使用它,而不是在DB中创建它?
由于
答案 0 :(得分:1)
你不能在SP内“创建”或定义一个函数,没有。您必须在/ a数据库上创建它,然后引用您创建的对象。
如果由于某些奇怪的原因你不希望保留该对象,你可以在TempDB中DROP
,使用它,然后/**
* Required: set 'ot_theme_mode' filter to true.
*/
add_filter( 'ot_theme_mode', '__return_true' );
/**
* Required: include OptionTree.
*/
require( trailingslashit( get_template_directory() ) . 'option-tree/ot-loader.php' );
它(但是这意味着SP不能同时由两个用户运行,因为该对象已经存在)。
只需永久创建它。
答案 1 :(得分:1)
在数据库中创建一个像这样的函数......
CREATE FUNCTION dbo.run_date_calc
(
@d1 datetime
, @d2 datetime
)
RETURNS VARCHAR(100)
AS
BEGIN
Declare @year int, @month int, @d int;
SET @year = datediff(year, @d1, @d2) - 1
SET @month = datediff(month, dateadd(year, @year, @d1), @d2)
IF dateadd(month, @month, dateadd(year, @year, @d1)) > @d2 set @month = @month - 1
set @d = datediff(day, dateadd(month, @month, dateadd(year, @year, @d1)), @d2)
RETURN ( cast(@year as varchar(10)) + ' year(s) '
+ cast(@month as varchar(10)) + ' month(s) and '
+ cast(@d as varchar(10)) + ' day(s)'
)
END
GO
然后只需从你的proc
调用CREATE PROCEDURE [dbo].[stp__getClients]
AS
BEGIN
SET NOCOUNT ON;
Select Id,Name,Status ,
(CASE WHEN Status = 3 then dbo.run_date_calc(FromDate , ToDate) else ''
end) as DateRangeDesc
From ClientsTbl
...
END
GO
答案 2 :(得分:1)
正如您所知,您无法在SP内定义功能。 此外,您的功能不正确。 看看我的解决方案:
declare @d1 datetime, @d2 datetime, @year int, @month int, @d int
set @d1 = '2009-09-24'
set @d2 = '2012-04-23'
SET @year = NULLIF(DATEDIFF(year, @d1, @d2), 0)
IF @year IS NOT NULL AND DATEADD(year, @year, @d1) > @d2
SET @year = NULLIF(@year - 1, 0)
SET @month = NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(@year, 0), @d1), @d2), 0)
IF DATEADD(month, ISNULL(@month, 0), DATEADD(year, ISNULL(@year, 0), @d1)) > @d2
set @month = NULLIF(@month - 1, 0)
set @d = DATEDIFF(day, DATEADD(month, ISNULL(@month, 0), DATEADD(year, ISNULL(@year, 0), @d1)), @d2)
SELECT ISNULL(cast(@year as nvarchar) + ' year(s) ', '') + ISNULL(cast(@month as nvarchar) + ' month(s) and ', '') + cast(@d as nvarchar) + ' day(s)'
而不是使用函数你可以使用CASE
语句,但在我看来,它看起来很糟糕:
SELECT
--Years
ISNULL(cast(
CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END
AS VARCHAR) + ' year(s) ', '')
--Months
+ ISNULL(cast(
CASE WHEN DATEADD(month, ISNULL(NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END, 0), @d1), @d2), 0), 0), DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END, 0), @d1)) > @d2
THEN NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END, 0), @d1), @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END, 0), @d1), @d2), 0)
END
AS VARCHAR) + ' month(s) ', '')
--Days
+ cast(DATEDIFF(day, DATEADD(month, ISNULL(CASE WHEN DATEADD(month, ISNULL(NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END, 0), @d1), @d2), 0), 0), DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END, 0), @d1)) > @d2
THEN NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END, 0), @d1), @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END, 0), @d1), @d2), 0)
END, 0), DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2
THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0)
ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0)
END , 0), @d1)), @d2) as nvarchar) + ' day(s)'