使用多个CTE和一个INSERT语句。 [错误:比列表中指定的列数更多]

时间:2018-04-01 15:25:04

标签: sql sql-server database sql-server-2016

我有CTE1和CTE2如下。 CTE2显示错误

CTE2 has more columns than specified in the column list

我想知道我做错了什么。它不能是因为Insert语句有比CTE2更多的列,因为CTE1之前工作正常。 CTE1和CTE2都使用不同的表。这是问题吗?

如果删除CTE2(NewRoomCost,NewQuantity)中的参数,则会出现错误

No Columns specified for Column3 of CTE2

以下是我尝试过的代码。任何帮助将不胜感激。

CREATE PROCEDURE dbo.SpTransactionGenerate
AS
BEGIN
SET NOCOUNT ON

    DECLARE @MinReservationId INT = (SELECT MIN(f.ReservationId) FROM dbo.Reservation AS f)
    DECLARE @MaxReservationId INT = (SELECT MAX(f.ReservationId) FROM dbo.Reservation AS f)

    DECLARE @FirstSeasonEndDate DATE= '2018-02-13';
    DECLARE @SecondSeasonEndDate DATE='2018-02-14';
    DECLARE @ThirdSeasonEndDate DATE='2018-12-31';

    WHILE @MinReservationId<=@MaxReservationId
    BEGIN   
        WITH CTE1(ServiceId,ServiceRate,Quantity) AS 
        (
           SELECT ServiceId,
                  ServiceRate,
                  ABS(CHECKSUM(NEWID())%3) + 1 AS Quantity 
           FROM dbo.[Service]                              
        ),
        CTE2(NewRoomCost,NewQuantity) AS 
        (
           SELECT 
                (SELECT roomRate.RoomCost FROM dbo.RoomRate as roomRate WHERE roomRate.RoomTypeId=
                (SELECT room.RoomTypeId FROM dbo.Room as room
                JOIN dbo.Reservation as res ON res.RoomId=room.RoomId WHERE res.ReservationId=@MinReservationId
                AND roomRate.SeasonId=(
                CASE WHEN (SELECT resv.CheckInDate FROM dbo.Reservation as resv WHERE resv.ReservationId=@MinReservationId)<=@FirstSeasonEndDate
                THEN (SELECT sea.SeasonId FROM dbo.Season as sea WHERE sea.SeasonEndDate=@FirstSeasonEndDate)
                WHEN (SELECT resv.CheckInDate FROM dbo.Reservation as resv WHERE resv.ReservationId=@MinReservationId)<=@SecondSeasonEndDate
                THEN (SELECT sea.SeasonId FROM dbo.Season as sea WHERE sea.SeasonEndDate=@SecondSeasonEndDate)
                ELSE (SELECT sea.SeasonId FROM dbo.Season as sea WHERE sea.SeasonEndDate=@ThirdSeasonEndDate) END
                )
                )) AS NewRoomCost,

                DATEDIFF(DAY,(SELECT r.CheckinDate FROM dbo.Reservation AS r WHERE r.ReservationId=@MinReservationId), (SELECT r.CheckOutDate FROM dbo.Reservation AS r WHERE r.ReservationId=@MinReservationId)) AS NewQuantity,                                                  
        )

        INSERT INTO dbo.[Transaction]
        (
            ReservationId,
            ServiceId,
            Rate,
            Quantity,
            Amount              
        )   
        SELECT 
            @MinReservationId,
            ServiceId,
            ServiceRate,
            Quantity,
            ServiceRate*Quantity
            FROM CTE1
            UNION
        SELECT 
            @MinReservationId,
            NULL,
            NewRoomCost,
            NewQuantity,
            NewRoomCost*NewQuantity
            FROM CTE2

        SELECT @MinReservationId=@MinReservationId+1    
    END
END

更新:由于CTE2中有一个额外的逗号而导致错误。对不起,提出了不必要的问题。

2 个答案:

答案 0 :(得分:2)

CTE2中的问题是,此行末尾有一个额外的逗号:

DATEDIFF(DAY,(SELECT r.CheckinDate FROM dbo.Reservation AS r WHERE r.ReservationId=@MinReservationId), (SELECT r.CheckOutDate FROM dbo.Reservation AS r WHERE r.ReservationId=@MinReservationId)) AS NewQuantity, 

旁注:我建议将来不要编写明确的列名,而只是像使用AS关键字那样命名它们。它只是提供了更大的灵活性。

答案 1 :(得分:0)

因为您的第二个CTE定义了两列:

CTE2(NewRoomCost,NewQuantity) AS

但是你的select语句返回3。

(SELECT roomRate.RoomCost FROM...

DATEDIFF(DAY,(SELECT r.CheckinDate...

(SELECT r.CheckOutDate FROM dbo.Reservation...