为啥 SQL 服务器在我的表中插入 0 值而不是使用函数的正确值
Posted
技术标签:
【中文标题】为啥 SQL 服务器在我的表中插入 0 值而不是使用函数的正确值【英文标题】:Why is SQL server inserting 0 values into my table instead of the correct values using function为什么 SQL 服务器在我的表中插入 0 值而不是使用函数的正确值 【发布时间】:2017-06-29 21:55:35 【问题描述】:希望有人可以帮助我解决这个问题,因为我完全不知道为什么会这样。
我目前正在对英超联赛的比赛结果进行一些分析,作为其中的一部分,我创建了一个多语句表 UDF。
此函数接受 HomeTeam、AwayTeam 和 MatchDate 参数,然后计算在指定的比赛日期之前主队和客队之间历史上赢、平或输的每场比赛结果。
这个函数手动调用就可以正常工作,返回值如
Home Away Draw
0 8 4
我想将此信息添加到我的匹配表中的每个匹配结果中,因此创建了一个查询以从临时表中移动匹配项,使用 OUTER APPLY 和插入这些值的函数。(我还 OUTER APPLY 之前的另一个函数到这个工作正常。)然后插入到我的 MatchData 表中。
如果我只选择值,则查询有效,但如果我插入到我的 MatchData 表中,则这些值都填充为 0。
我已经尝试了很多测试,这些测试确认如果我使用 SELECT into 也会发生这种情况,除非表是临时的。
要补充的是,在任何时候都没有转换有问题的值,它们一直保持为整数,并且目标列也是 int 类型。
希望有人能给我一些关于下一步尝试的想法。代码如下。对任何写得不好的地方表示歉意,因为到目前为止我已经混淆了很多代码,试图让它插入正确的值
提前致谢!
这是存储过程:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [Load].[MoveToMatchData]
AS
BEGIN
INSERT INTO Football.MatchData.PremierLeague
SELECT *
FROM
(SELECT
[League], [MatchID], [Season],
[MatchDate], [HomeTeam], [AwayTeam],
[FTHomeGoals], [FTAwayGoals], [FTResult],
[HTHomeGoals], [HTAwayGoals], [HTResult],
[Referee], [HomeShots], [AwayShots],
[HomeShotsOnTarget], [AwayShotsOnTarget],
[HomeFouls], [AwayFouls], [HomeCorners], [AwayCorners],
[HomeYellows], [AwayYellows], [HomeReds], [AwayReds]
FROM
[Football].[Load].[Staging_MatchData] AS a
WHERE
League = 'E0') AS a
OUTER APPLY
(
SELECT * FROM Football.Load.CreateRelativeTable_Prem
(a.MatchDate, a.HomeTeam, a.AwayTeam, a.Season, A.League)
) as b
OUTER APPLY
这是 UDF
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [Load].[GetH2HRecords]
(@HomeTeam varchar(50), @AwayTeam varchar(50), @MatchDate date)
RETURNS @H2H TABLE
(
Home int,
Away int,
Draw int
)
AS
BEGIN
DECLARE @FromDate date
SET @FromDate = DATEADD(yyyy,-10,@MatchDate)
INSERT INTO @H2H
SELECT
a.[Number of Matches] as HomeHTH, b.[Number of Matches] as AwayHTH, c.[Number of Matches] as DrawHTH
FROM
(
SELECT
COUNT(MatchID) as [Number of Matchesh]
FROM MatchData.PremierLeague
WHERE HomeTeam = @HomeTeam
AND AwayTeam = @AwayTeam
AND MatchDate > @FromDate
AND FTResult = 'H'
) as a
OUTER APPLY
(
SELECT
COUNT(MatchID) as [Number of Matchesa]
FROM MatchData.PremierLeague
WHERE HomeTeam = @HomeTeam
AND AwayTeam = @AwayTeam
AND MatchDate > @FromDate
AND FTResult = 'A'
) as b
OUTER APPLY
(
SELECT
COUNT(MatchID) as [Number of Matchesd]
FROM MatchData.PremierLeague
WHERE HomeTeam = @HomeTeam
AND AwayTeam = @AwayTeam
AND MatchDate > @FromDate
AND FTResult = 'D'
) as c
RETURN
END
(
SELECT * FROM Football.Load.GetH2HRecords
(a.HomeTeam, a.AwayTeam, a.MatchDate)
) as c
END
【问题讨论】:
表名中有数据库有什么原因吗?您是否插入到不同的(链接的?)服务器? 查询中不涉及链接服务器,我发现完全限定我的表名对我来说效果更好,因为它可以阻止事情进入默认数据库,因为我经常处理不同的项目,这些项目位于不同的数据库等。此外,在这个项目中,我计划创建多个数据库,其中包含我要分析的数据的不同部分,只是为了保持整洁。 您应该始终在 INSERT INTO 上使用显式列列表,在 SELECT 查询上使用显式列列表。如果这不能解决问题,请尝试创建一个小的问题重现。 【参考方案1】:这只是一个潜在的答案,但是……为什么您的函数查询如此复杂?这仅在一个 SELECT 语句中执行相同的操作:
CREATE FUNCTION [Load].[GetH2HRecords]
(@HomeTeam varchar(50), @AwayTeam varchar(50), @MatchDate date)
RETURNS @H2H TABLE
(
Home int,
Away int,
Draw int
)
AS
BEGIN
DECLARE @FromDate date
SET @FromDate = DATEADD(yyyy,-10,@MatchDate)
INSERT INTO @H2H
SELECT
SUM(
CASE
WHEN FTResult = 'H'
Then 1
ELSE 0
END
) as HomeHTH,
SUM(
CASE
WHEN FTResult = 'A'
Then 1
ELSE 0
END
) as AwayHTH,
SUM(
CASE
WHEN FTResult = 'D'
Then 1
ELSE 0
END
) as DrawHTH
FROM MatchData.PremierLeague
WHERE HomeTeam = @HomeTeam
AND AwayTeam = @AwayTeam
AND MatchDate > @FromDate
RETURN
END
【讨论】:
谢谢 Laughing Vergil,我回家后试试这个。我以易于阅读/简单的方式设置它,因为原始查询计算出每个计数的百分比。由于它不起作用,我决定将其删除,并决定如果我可以将计数放入表中,我将在表中添加一个计算列以显示百分比。我希望有一些明显的问题,这样我就不必像你一样重新编写查询,但也许这是唯一的解决方案。 您可以随时添加一个额外的列COUNT(*) As Total
,并添加一个 AND 子句 - AND FTResult IN ('H', 'A', 'D')
- 到查询中,然后在显示层中即时计算百分比,或者在选择时来自临时表。以上是关于为啥 SQL 服务器在我的表中插入 0 值而不是使用函数的正确值的主要内容,如果未能解决你的问题,请参考以下文章