SQL Server Trigger Error Message
<p>This is the error I am getting:</p>

<blockquote>
  <p>Msg 512, Level 16, State 1, Procedure tr_UpdateFolio, Line 361<br>
  Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, &lt;, &lt;= , >, >= or when the subquery is used as an expression.</p>
</blockquote>

<p>I've run up and down this code over and over for hours now. What am I not seeing? Any help would be appreciated. I've been working on this for a few days now, and this is pretty much the one thing I need working in order to get this project done.</p>

<pre><code>-- 2. Write a trigger named tr_UpdateFolio  that will be invoked when the Folio table 'status' 
-- field ONLY (column update) is changed.
ALTER TRIGGER tr_UpdateFolio ON FOLIO--switch alter back to create
AFTER UPDATE
AS
    IF UPDATE([Status])
    BEGIN
        DECLARE @Status char(1)
        DECLARE @FolioID smallint
        DECLARE @CheckinDate smalldatetime
        DECLARE @Nights tinyint
        DECLARE @CurrentDate smalldatetime = '7/27/2016 2:00:00 PM'

        SELECT 
            @Status = i.Status, 
            @FolioID = i.FolioID,  
            @CheckinDate = i.CheckinDate, 
            @Nights = i.Nights
        FROM 
            INSERTED i

        -- If Folio status is updated to 'C' for Checkout, trigger two different Insert statements to 
        -- (1) INSERT in the Billing table, the amount for the total lodging cost as BillingCategoryID1
        -- -  (normally the FolioRate * number of nights stay, but you must  also factor in any late checkout fees*). 
        -- *Checkout time is Noon on the checkout date. Guest is given a one hour 
        -- grace period to check out. After 1PM (but before 4PM), a 50% surcharge is added to the FolioRate. After 4PM, an 
        -- additional full night's FolioRate is applied. You can recycle code from A7  (part 5), but note it's not the exact same 
        -- function - we only need the late charge (if any).

        IF @Status = 'C'
           SET @Nights = 1

        --@CurrentDate may need to switch back to getdate()
        IF DATEDIFF(HOUR, @CheckinDate + @Nights, @CurrentDate) &gt;= 16
            SET @Nights = @Nights + 1
        ELSE IF DATEDIFF(HOUR, @CheckinDate + @Nights, @CurrentDate) &gt;= 13
            SET @Nights = @Nights + .5

        UPDATE FOLIO
        SET Nights = @Nights
        WHERE FolioID = @FolioID

        INSERT INTO BILLING (FolioID, BillingCategoryID, BillingDescription, BillingAmount, BillingItemQty, BillingItemDate)
        VALUES (25, 1, 'Room', dbo.GetRackRate(11, @CurrentDate) * @Nights, 1, @CurrentDate)

        -- (2) The second INSERT statement in the same trigger will insert the Lodging Tax* - as a separate entry in the 
        -- Billing table for tax on lodging (BillingCategoryID2).  *Use the dbo.GetRoomTaxRate function from A7 to determine 
        -- the Lodging Tax.  
        INSERT INTO BILLING (FolioID, BillingCategoryID, BillingDescription, BillingAmount, BillingItemQty, BillingItemDate)
        VALUES (25, 2, 'Lodging Tax', dbo.GetRoomTaxRate(20), 1, @CurrentDate)
END
GO

-- 3. Write a trigger named tr_GenerateBill that will be invoked when an entry is INSERTED in to the Billing 
-- table. If BillngCategoryID is 2 (for testing purposes only) then call the function dbo.ProduceBill (from A7).

ALTER TRIGGER tr_GenerateBill ON BILLING
AFTER INSERT
AS
BEGIN
DECLARE @FolioID smallint
DECLARE @BillingCategoryID smallint

SELECT @FolioID = i.FolioID, @BillingCategoryID = i.BillingCategoryID
FROM INSERTED i

IF @BillingCategoryID = 2
SELECT * FROM dbo.ProduceBill(@FolioID)
END
GO
</code></pre>

<p>dbo.producebill should be fine, but the error occurs when I try to run this block</p>

<pre><code>-- 4A. Assume today is (July 27, 2016 at 2PM)*. Anita is due to check out today (from Part 1 above).
-- Write an Update Statement to change the status of her Folio to 'CheckedOut.
-- (Be careful to include a WHERE clause so ONLY here folio is updated).
-- Note: This should automatically invoke tr_UpdateFolio above (factoring in the late charge),
-- which automatically invokes tr_GenerateBill  above, and calls dbo.ProduceBill , and produces a bill.

UPDATE FOLIO
SET [Status] = 'C'
WHERE ReservationID = 5020
</code></pre>

<p>I'm going nuts trying to figure this out. Thanks.</p>