この私が取得していますエラーです:SQL Serverのトリガーエラーメッセージ
をメッセージ512、レベル16、状態1、プロシージャtr_UpdateFolio、ライン361
サブクエリは複数の値を返しました。 =、!=、<、< =、>、> =、またはサブクエリが式として使用されている場合は、これは許可されません。
私は今このコードを何時間も繰り返し実行してきました。私は何を見ていないのですか?どんな助けもありがとう。私は数日間この作業に取り組んできましたが、これはこのプロジェクトを完了させるために必要な作業です。
-- 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
[email protected] may need to switch back to getdate()
IF DATEDIFF(HOUR, @CheckinDate + @Nights, @CurrentDate) >= 16
SET @Nights = @Nights + 1
ELSE IF DATEDIFF(HOUR, @CheckinDate + @Nights, @CurrentDate) >= 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
dbo.producebillは問題ないはずですが、私は、私はこれを理解しようとしているナットつもり
-- 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
このブロックを実行しようとするとエラーが発生します。ありがとう。
トリガーには大きな欠陥があります。一度に1つの行だけが挿入されると仮定しています。これは、SQL Serverでトリガーが動作する方法ではありません。 1回の操作ではなく、1回の操作で1回発射されます。あなたはこれに基づいてロジックを設定する必要があります。これらのスカラー関数を取り除くことを検討するかもしれません、彼らは悪名高い貧しいパフォーマーです。 –
私はこれを修正する必要があるとは思わない。私はちょうどトリガーを学んでいるので、それはこれになるとまだ少し不安です。 – Godfried23
ENTIREトリガーは、どちらも単一の行の概念に基づいて設計されています。それらは両方ともセットを扱うために完全に再構築する必要があります。 –