交叉应用于标量值和 table 值函数
Cross apply on both scalar-valued and table-valued functions
我的存储过程使用交叉应用到 运行 select 中的几个函数。其中 3 个函数是标量值,而最后一个是 table 值。
ALTER PROCEDURE [dbo].[GetThreadsInArea]
@CountryCode nvarchar(10),
@Latitude float,
@Longtitude float,
@DistanceInKm int,
@Offset int,
@UserID int
AS
BEGIN
SELECT t.ID, t.[Date], t.[Text], t.Points, func.Distance, func.Messages, t.Color, func.IsOwnThread, func.HasVotedIsUpvote
FROM dbo.Threads as t
CROSS APPLY
( Select
dbo.fnCalcDistanceKM(t.Latitude, @Latitude, t.Longtitude, @Longtitude) as Distance, -- Scalar-valued
dbo.GetThreadCommentCount(t.ID) as [Messages], -- Scalar-valued
dbo.IsOwnThread(t.ID, @UserID) as IsOwnThread, -- Scalar-valued
dbo.HasVotedIsUpvote(t.ID, @UserID) as HasVotedIsUpvote -- Table-valued
) as func
WHERE t.CountryCode = @CountryCode AND func.Distance < @DistanceInKm
ORDER BY t.Date desc
OFFSET @Offset ROWS
FETCH NEXT 20 ROWS ONLY
END
这个命令完成得很好,但是当我尝试 运行 执行它时,我得到:
Msg 4121, Level 16, State 1, Procedure dbo.GetThreadsInArea, Line 10 [Batch Start Line 0]
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.HasVotedIsUpvote", or the name is ambiguous.
(1 row(s) affected)
受影响的第 1 行也让我感到困惑。存储过程不应更改任何行上的任何数据。是从 table 值函数返回的行受到影响吗?
编辑:
这就是程序现在的样子,尽管我不喜欢在 SELECT 和 WHERE 中使用 dbo.fnCalcDistanceKM 两次。有什么解决办法吗?
ALTER PROCEDURE [dbo].[GetThreadsInArea]
@CountryCode nvarchar(10),
@Latitude float,
@Longtitude float,
@DistanceInKm int,
@Offset int,
@UserID int
AS
BEGIN
SELECT t.ID,
t.[Date],
t.[Text],
t.Points,
**dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude)** AS Distance,
dbo.Getthreadcommentcount(t.ID) AS [Messages],
t.Color,
dbo.Isownthread(t.ID, @UserID) AS IsOwnThread,
func.HasVoted,
func.IsUpvote
FROM dbo.Threads AS t
CROSS APPLY dbo.Hasvotedisupvote(t.ID, @UserID) func
WHERE t.CountryCode = @CountryCode
AND **dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude)** < @DistanceInKm
ORDER BY t.Date DESC
OFFSET @Offset ROWS
FETCH NEXT 20 ROWS ONLY
END
我尝试使用它的别名 Distance,但它只告诉我:
Msg 207, Level 16, State 1, Procedure GetThreadsInArea, Line 22 [Batch Start Line 7]
Invalid column name 'Distance'.
为什么要将 scalar
函数放在 cross apply
中,只需在 Select
中使用它,而在 cross apply
中单独使用 table 值函数。像这样
SELECT t.ID,
t.[Date],
t.[Text],
t.Points,
dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude) AS Distance,
dbo.Getthreadcommentcount(t.ID) AS [Messages],
t.Color,
dbo.Isownthread(t.ID, @UserID) AS IsOwnThread,
func.HasVoted,
func.IsUpvote
FROM dbo.Threads AS t
CROSS APPLY dbo.Hasvotedisupvote(t.ID, @UserID) func
WHERE t.CountryCode = @CountryCode
AND dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude) < @DistanceInKm
ORDER BY t.Date DESC
OFFSET @Offset ROWS FETCH NEXT 20 ROWS ONLY
关于 (1 行受影响) 您是否启用了执行计划?
如果您不想两次使用该函数,那么您可以使用派生的 table 或在 CROSS APPLY
中单独使用该函数
SELECT t.ID,
t.[Date],
t.[Text],
t.Points,
cs.Distance,
dbo.Getthreadcommentcount(t.ID) AS [Messages],
t.Color,
dbo.Isownthread(t.ID, @UserID) AS IsOwnThread,
func.HasVoted,
func.IsUpvote
FROM dbo.Threads AS t
CROSS APPLY dbo.Hasvotedisupvote(t.ID, @UserID) func
cross apply (select dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude))cs (Distance)
WHERE t.CountryCode = @CountryCode
AND cs.Distance < @DistanceInKm
ORDER BY t.Date DESC
OFFSET @Offset ROWS FETCH NEXT 20 ROWS ONLY
我的存储过程使用交叉应用到 运行 select 中的几个函数。其中 3 个函数是标量值,而最后一个是 table 值。
ALTER PROCEDURE [dbo].[GetThreadsInArea]
@CountryCode nvarchar(10),
@Latitude float,
@Longtitude float,
@DistanceInKm int,
@Offset int,
@UserID int
AS
BEGIN
SELECT t.ID, t.[Date], t.[Text], t.Points, func.Distance, func.Messages, t.Color, func.IsOwnThread, func.HasVotedIsUpvote
FROM dbo.Threads as t
CROSS APPLY
( Select
dbo.fnCalcDistanceKM(t.Latitude, @Latitude, t.Longtitude, @Longtitude) as Distance, -- Scalar-valued
dbo.GetThreadCommentCount(t.ID) as [Messages], -- Scalar-valued
dbo.IsOwnThread(t.ID, @UserID) as IsOwnThread, -- Scalar-valued
dbo.HasVotedIsUpvote(t.ID, @UserID) as HasVotedIsUpvote -- Table-valued
) as func
WHERE t.CountryCode = @CountryCode AND func.Distance < @DistanceInKm
ORDER BY t.Date desc
OFFSET @Offset ROWS
FETCH NEXT 20 ROWS ONLY
END
这个命令完成得很好,但是当我尝试 运行 执行它时,我得到:
Msg 4121, Level 16, State 1, Procedure dbo.GetThreadsInArea, Line 10 [Batch Start Line 0]
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.HasVotedIsUpvote", or the name is ambiguous.
(1 row(s) affected)
受影响的第 1 行也让我感到困惑。存储过程不应更改任何行上的任何数据。是从 table 值函数返回的行受到影响吗?
编辑:
这就是程序现在的样子,尽管我不喜欢在 SELECT 和 WHERE 中使用 dbo.fnCalcDistanceKM 两次。有什么解决办法吗?
ALTER PROCEDURE [dbo].[GetThreadsInArea]
@CountryCode nvarchar(10),
@Latitude float,
@Longtitude float,
@DistanceInKm int,
@Offset int,
@UserID int
AS
BEGIN
SELECT t.ID,
t.[Date],
t.[Text],
t.Points,
**dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude)** AS Distance,
dbo.Getthreadcommentcount(t.ID) AS [Messages],
t.Color,
dbo.Isownthread(t.ID, @UserID) AS IsOwnThread,
func.HasVoted,
func.IsUpvote
FROM dbo.Threads AS t
CROSS APPLY dbo.Hasvotedisupvote(t.ID, @UserID) func
WHERE t.CountryCode = @CountryCode
AND **dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude)** < @DistanceInKm
ORDER BY t.Date DESC
OFFSET @Offset ROWS
FETCH NEXT 20 ROWS ONLY
END
我尝试使用它的别名 Distance,但它只告诉我:
Msg 207, Level 16, State 1, Procedure GetThreadsInArea, Line 22 [Batch Start Line 7]
Invalid column name 'Distance'.
为什么要将 scalar
函数放在 cross apply
中,只需在 Select
中使用它,而在 cross apply
中单独使用 table 值函数。像这样
SELECT t.ID,
t.[Date],
t.[Text],
t.Points,
dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude) AS Distance,
dbo.Getthreadcommentcount(t.ID) AS [Messages],
t.Color,
dbo.Isownthread(t.ID, @UserID) AS IsOwnThread,
func.HasVoted,
func.IsUpvote
FROM dbo.Threads AS t
CROSS APPLY dbo.Hasvotedisupvote(t.ID, @UserID) func
WHERE t.CountryCode = @CountryCode
AND dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude) < @DistanceInKm
ORDER BY t.Date DESC
OFFSET @Offset ROWS FETCH NEXT 20 ROWS ONLY
关于 (1 行受影响) 您是否启用了执行计划?
如果您不想两次使用该函数,那么您可以使用派生的 table 或在 CROSS APPLY
SELECT t.ID,
t.[Date],
t.[Text],
t.Points,
cs.Distance,
dbo.Getthreadcommentcount(t.ID) AS [Messages],
t.Color,
dbo.Isownthread(t.ID, @UserID) AS IsOwnThread,
func.HasVoted,
func.IsUpvote
FROM dbo.Threads AS t
CROSS APPLY dbo.Hasvotedisupvote(t.ID, @UserID) func
cross apply (select dbo.Fncalcdistancekm(t.Latitude, @Latitude, t.Longtitude, @Longtitude))cs (Distance)
WHERE t.CountryCode = @CountryCode
AND cs.Distance < @DistanceInKm
ORDER BY t.Date DESC
OFFSET @Offset ROWS FETCH NEXT 20 ROWS ONLY