SQL Server Insertar consulta en la tabla de hecho
-
14-09-2020 - |
Pregunta
De acuerdo, así que tengo este problema con mi tabla de hechos.Necesito que se llene automáticamente cuando se ingrese nuevos datos en todas las otras tablas en la base de datos que tiene una clave externa en la tabla de datos.En mi procedimiento almacenado, compilé todas las declaraciones de inserción que tengo y al final, ya que también quiero actualizar mi tabla de hechos, coloco esta consulta:
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)
Sin embargo, recibo un error con el siguiente mensaje:
Subqueries are not allowed in this context. Only scalar expressions are allowed.
¿Puede alguien por favor ayudarme?Muchas gracias.:)
Mi procedimiento completo:
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
Solución
Suponiendo que las subvisas pueden devolver solo un registro, esto debería funcionar
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)
Otros consejos
No puede hacer subconsultas con un inserto de vainilla, debe hacer un inserto ... Seleccione:
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)
También miraría el plan de ejecución para ello para los posibles cuellos de la botella de rendimiento, y también mirar los índices sobre las tablas de gastos, datos e inventario.
Cambia tu consulta para ser esto:
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)