2017-11-16 7 views
1

私はビューを作成していますが、フィールドがnullableに変換される理由について少し混乱しています。私は、SQL Server 2016SQL Server:cross applyによって列がNULLに設定される

CREATE OR ALTER VIEW [dbo].[vwEmployeePTORequest] 
AS 
    SELECT 
     Employees.EmployeeID, Employees.DivisionID, 
     PTORequests.PTORequestId, PTORequests.IsPaidOut, 
     PTORequests.PayoutPayEntryEarningId, 
     --Why do I have to use ISNULL here? 
     ISNULL(SummaryDetails.TotalHours, 0) AS TotalHours, 
     SummaryDetails.RequestStartDate, SummaryDetails.RequestEndDate, 
     SummaryDetails.DivisionPTOAccrualId 
    FROM 
     dbo.Employees 
    INNER JOIN 
     dbo.GlobalIds ON Employees.GlobalId = GlobalIds.Id 
    INNER JOIN 
     dbo.Activities ON Activities.OriginatorGlobalId = GlobalIds.Id 
    INNER JOIN 
     dbo.PTORequests ON Activities.ActivityId = PTORequests.ActivityId 
    CROSS APPLY 
     dbo.GetEmployeePTORequestDetailSummary(PTORequests.PTORequestId) AS SummaryDetails; 

を使用していますそして、これはCROSS APPLYに呼び出される関数です。

CREATE OR ALTER FUNCTION [dbo].[GetEmployeePTORequestDetailSummary] 
    (@PTORequestId INT) 
RETURNS TABLE 
AS 
    RETURN 
     (SELECT TOP 1 
      SUM(Hours) AS TotalHours, 
      MIN(RequestDate) AS RequestStartDate, 
      MAX(RequestDate) AS RequestEndDate, 
      DivisionPTOAccrualId AS DivisionPTOAccrualId 
     FROM 
      dbo.PTORequestDetails 
     WHERE 
      PTORequestId = @PTORequestId 
     GROUP BY 
      PTORequestId, DivisionPTOAccrualId); 

そして、これは、テーブル定義の関連部分である:

CREATE TABLE [dbo].[PTORequestDetails] 
(
    [PTORequestDetailId] [int] IDENTITY(1,1) NOT NULL, 
    [RequestDate] [date] NOT NULL, 
    [StartTime] [datetime] NULL, 
    [Hours] [decimal](19, 2) NOT NULL, 
) 

なぜこれが起こっているのか、私は少し混乱しています。列がNULLABLEではないことがわかるように、集計関数はnullを許可しない型を返します。内側の結合と同様に行ごとに動作するCROSS APPLYを使用しています。それは1対1であるため、null可能ではありません。

誰も私の列がnullableとして入って来る理由を説明することができますし、それを使用して他のすべてのプロシージャが各選択された列の条件付きISNULL()を指定する必要はありません。

+2

クロスが適用されるわけではありません。これは集合関数です。 SUM、MIN、MAXはすべて、NULLを返すため、GROUP BYのない空のテーブルでそれらを使用すると、NULL可能であるとみなされます。 –

+0

@MartinSmithあなたの応答のためにありがとう、それは奇妙です。なぜなら、私はintellisenseを使用して、それがintを返してくるからです。 –

+0

intを返します。しかしヌル可能。 http://rextester.com/EUGVE39896 –

答えて

4

これはクロス・プリミティブではありません。これは集合関数です。 SUM、MIN、MAXはすべて、NULLを返すため、GROUP BYのない空のテーブルでそれらを使用すると、NULL可能であるとみなされます。

さらに、廃止予定のセッションオプションを使用すると、SUMは整数オーバーフロー時にエラーではなくNULLを返すことができます。

ISNULLに集約をラップして、その列をヌル可能でないものとして扱う必要があります。

関連する問題