views:

41

answers:

3

Okay, so I have this problem with my Fact Table. I need it to automatically be filled when a new data is entered on all the other tables in the database which has a foreign key on my Fact Table. In my stored procedure, I compiled all the insert statements I have and at the end, since I also want to update my Fact Table, I place this query:

INSERT INTO Fact (AccountID, ExpenseID, DateTimeID, InventoryID)
VALUES (@AccountID, 
        (SELECT ExpenseID FROM Expenses WHERE WaterBill = @WaterBill AND ElectricBill = @ElectricBill AND OfficeRent = @OfficeRent,
        SELECT DateTimeID FROM DateTime WHERE MonthNo = @MonthNo AND Date = @Date AND Year = @Year AND Time = @Time AND Day = @Day AND DayNo = @DayNo,
        SELECT InventoryID FROM Inventory WHERE ProductInID = @ProductInID AND ProductOutID = @ProductOutID)

However, I get an error with the following message:

Subqueries are not allowed in this context. Only scalar expressions are allowed.

Can anybody please help me? Thanks a lot. :)

MY COMPLETE PROCEDURE:

    ALTER PROCEDURE [dbo].[ExpenseListInsert]
    @AccountID char(6),
    @ExpenseID int,
    @DateTimeID int,
    @InventoryID int,
    @WaterBill decimal(19, 4),
    @ElectricBill decimal(19, 4),
    @OfficeRent decimal(19, 4),
    @Miscellaneous decimal(19, 4),
    @ProductsExpense decimal(19, 4),
    @Subtotal decimal(19, 4),
    @ProductInID int,
    @ProductOutID int,
    @Product30001 int,
    @Product30002 int,
    @Product30003 int,
    @MonthNo int,
    @Date int,
    @Year int,
    @Time char(11),
    @Day char(10),
    @DayNo int
AS
    INSERT INTO Expenses (WaterBill, ElectricBill, OfficeRent, Miscellaneous, ProductsExpense, Subtotal)
    VALUES(@WaterBill, @ElectricBill, @OfficeRent, @Miscellaneous, @ProductsExpense, @Subtotal)

    INSERT INTO ProductIn (ProductInID, Product30001, Product30002, Product30003)
    VALUES(@ProductInID, @Product30001, @Product30002, @Product30003)

    INSERT INTO ProductOut (ProductOutID, Product30001, Product30002, Product30003)
    VALUES(@ProductOutID, '0', '0', '0')

    INSERT INTO Inventory (ProductInID, ProductOutID)
    VALUES (@ProductInID, @ProductOutID) 

    INSERT INTO DateTime (MonthNo, Date, Year, Time, Day, DayNo)
    VALUES (@MonthNo, @Date, @Year, @Time, @Day, @DayNo)

    SELECT @ExpenseID = ExpenseID FROM Expenses WHERE WaterBill = @WaterBill AND ElectricBill = @ElectricBill AND OfficeRent = @OfficeRent

    SELECT @DateTimeID = DateTimeID FROM DateTime WHERE MonthNo = @MonthNo AND Date = @Date AND Year = @Year AND Time = @Time AND Day = @Day AND DayNo = @DayNo

    SELECT @InventoryID = InventoryID FROM Inventory WHERE ProductInID = @ProductInID AND ProductOutID = @ProductOutID

    INSERT INTO Fact (AccountID, ExpenseID, DateTimeID, InventoryID)
    VALUES (@AccountID, @ExpenseID, @DateTimeID, @InventoryID)
RETURN
A: 

Change your query to be this:

INSERT INTO Fact (AccountID, ExpenseID, DateTimeID, InventoryID) 
SELECT @AccountID,  
    (SELECT ExpenseID FROM Expenses WHERE WaterBill = @WaterBill AND ElectricBill = @ElectricBill AND OfficeRent = @OfficeRent), 
    (SELECT DateTimeID FROM DateTime WHERE MonthNo = @MonthNo AND Date = @Date AND Year = @Year AND Time = @Time AND Day = @Day AND DayNo = @DayNo), 
    (SELECT InventoryID FROM Inventory WHERE ProductInID = @ProductInID AND ProductOutID = @ProductOutID)
ck
this query gives me the following error messages:Msg 102, Level 15, State 1, Procedure ExpenseListInsert, Line 38Incorrect syntax near ','.Msg 102, Level 15, State 1, Procedure ExpenseListInsert, Line 39Incorrect syntax near ','.
Kim Rivera
@Kim Rivera - fixed. I thought you had bracketed each `SELECT`
ck
A: 

Assuming that the sub queries can each return only one record this should work

DECLARE @ExpenseID int, @DateTimeID int, @InventoryID int


SELECT @ExpenseID= ExpenseID FROM Expenses WHERE WaterBill = @WaterBill AND ElectricBill = @ElectricBill AND OfficeRent = @OfficeRent

SELECT @DateTimeID = DateTimeID FROM DateTime WHERE MonthNo = @MonthNo AND Date = @Date AND Year = @Year AND Time = @Time AND Day = @Day AND DayNo = @DayNo

SELECT @InventoryID = InventoryID FROM Inventory WHERE ProductInID = @ProductInID AND ProductOutID = @ProductOutID

INSERT INTO Fact (AccountID, ExpenseID, DateTimeID, InventoryID)
VALUES (@AccountID, @ExpenseID, @DateTimeID, @InventoryID)
Martin Smith
Sir, thanks for this. But I tried running this stored procedure. But each time I run my application, it gives me an error saying that my procedure expects an @ExpenseID parameter which was not supplied.I'll edit my question to put my stored procedure now. Thanks.
Kim Rivera
thanks. i got it working now :)
Kim Rivera
A: 

You can't do subqueries with a vanilla INSERT, you need to do an INSERT...SELECT:

INSERT INTO [Fact] (AccountID, ExpenseID, DateTimeID, InventoryID)
SELECT @AccountID, 
       (SELECT ExpenseID FROM [Expenses] WHERE WaterBill = @WaterBill AND ElectricBill = @ElectricBill AND OfficeRent = @OfficeRent),
       (SELECT DateTimeID FROM [DateTime] WHERE MonthNo = @MonthNo AND [Date] = @Date AND [Year] = @Year AND [Time] = @Time AND [Day] = @Day AND DayNo = @DayNo),
       (SELECT InventoryID FROM Inventory WHERE ProductInID = @ProductInID AND ProductOutID = @ProductOutID)

I'd also look at the execution plan for that for possible performance bottle necks, and also look at the indexes on the Expense, DateTime and Inventory tables.

Matthew Abbott
I don't understand what this query does. can you please explain to me? Thanks. :)
Kim Rivera
When you use VALUES with INSERT, you need to pass in SCALAR values. When you use SELECT with INSERT, you can pass in a tabular result set, in this case, the results of your three sub queries.
Matthew Abbott
This might sound stupid but I still don't get it. What i really would like to do is this:INSERT INTO Fact (A, B, C, D)VALUES (A, B should come from another table, C should come from another table, D should come from another table)Is this SELECT INSERT Applicable to this situation? Thanks a lot.
Kim Rivera
Well, that's what you are doing, when doing an INSERT INTO [Fact] (A, B, C, D) SELECT <value-for-A>, <value-for-B>, <value-for-C>, <value-for-D>, the values for B, C and D are the result fields from your subqueries on Expenses, DateTime and Inventory...
Matthew Abbott