Reputation: 3430
I have the following function that handles a trigger on insert or update:
CREATE OR REPLACE FUNCTION ticketChangeFunc() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO dw.FactSalesHeader (DateKey, LocationKey, EmployeeKey, AppointmentTypeKey, TicketStatusTypeKey, TicketID,TotalAmount, IsNewPatient, IsActive)
SELECT d.date_key, COALESCE(l.LocationKey, 0), COALESCE(e.EmployeeKey, 0), COALESCE(a.AppointmentTypeKey, 0), COALESCE(ts.TicketStatusTypeKey, 0), NEW.ticket_id,
NEW.total_amount, NEW.is_new_patient, NEW.is_active
FROM db1.tickets t
JOIN dw.DimDate d on t.ticket_date = d.db_date
LEFT JOIN dw.DimLocation l on NEW.location_id = l.LocationID
LEFT JOIN dw.DimEmployee e on NEW.counselor_id = e.EmployeeID
LEFT JOIN dw.DimAppointmentType a on NEW.office_visit_ind = a.AppointmentTypeFlagAttribute
LEFT JOIN dw.DimTicketStatus ts on NEW.ticket2_status = ts.TicketStatusTypeID
ON CONFLICT (TicketID)
DO UPDATE
SET DateKey = d.date_key,
LocationKey = COALESCE(l.LocationKey, 0),
EmployeeKey = COALESCE(e.EmployeeKey, 0),
AppointmentTypeKey = COALESCE(a.AppointmentTypeKey, 0),
TicketStatusTypeKey = COALESCE(ts.TicketStatusTypeKey, 0),
TotalAmount = NEW.total_amount,
IsNewPatient = NEW.is_new_patient,
IsActive = NEW.is_active;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
I get the error: missing FROM-clause entry for table "d"
I thought maybe it was somehow related to the db1.tickets
table that I'm not technically using in the query. I've tried taking out that bit and just doing FROM dw.DimDate
with WHERE d.date_key = NEW.ticket_date
, and that gives the same error.
There are a lot of these types of questions on SO, but I haven't found one that addresses this particular scenario, as I feel like it has something to do with it being inside of this trigger function.
The function gets called from this:
CREATE TRIGGER trg_tickets AFTER INSERT OR UPDATE ON db1.tickets
FOR EACH ROW EXECUTE PROCEDURE ticketChangeFunc();
I'm also wondering if using the ON CONFLICT UPDATE
clause updates every row when it finds a match regardless of whether the values differ? Is there a performance impact to this, and if so, is there a way to check for equality of each field and do nothing if there are no differences?
Upvotes: 1
Views: 1122
Reputation: 3430
For those who may happen to run into this in the future, the solution for me was to add a conditional to the function and handle inserts separately from updates:
CREATE OR REPLACE FUNCTION ticketChangeFunc() RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
INSERT INTO dw.FactSalesHeader (DateKey, LocationKey, EmployeeKey, AppointmentTypeKey, TicketStatusTypeKey, TicketID, TotalAmount, IsNewPatient, IsActive)
SELECT d.date_key, COALESCE(l.LocationKey, 0), COALESCE(e.EmployeeKey, 0), COALESCE(a.AppointmentTypeKey, 0), COALESCE(ts.TicketStatusTypeKey, 0), NEW.ticket_id,
NEW.total_amount, NEW.is_new_patient, NEW.is_active
FROM db1.tickets t
JOIN dw.DimDate d ON NEW.ticket_date = d.db_date
LEFT JOIN dw.DimLocation l ON NEW.location_id = l.LocationID
LEFT JOIN dw.DimEmployee e ON NEW.counselor_id = e.EmployeeID
LEFT JOIN dw.DimAppointmentType a ON NEW.office_visit_ind = a.AppointmentTypeFlagAttribute
LEFT JOIN dw.DimTicketStatus ts ON NEW.ticket2_status = ts.TicketStatusTypeID;
ELSE
UPDATE dw.FactSalesHeader
SET DateKey = CAST(TO_CHAR(NEW.ticket_date, 'YYYYMMDD') as integer),
LocationKey = COALESCE(l.LocationKey, 0),
EmployeeKey = COALESCE(e.EmployeeKey, 0),
AppointmentTypeKey = COALESCE(a.AppointmentTypeKey, 0),
TicketStatusTypeKey = COALESCE(ts.TicketStatusTypeKey, 0),
TotalAmount = NEW.total_amount,
IsNewPatient = NEW.is_new_patient,
IsActive = NEW.is_active
FROM dw.FactSalesHeader hdr
LEFT JOIN dw.DimLocation l ON NEW.location_id = l.LocationID
LEFT JOIN dw.DimEmployee e ON NEW.counselor_id = e.EmployeeID
LEFT JOIN dw.DimAppointmentType a ON NEW.office_visit_ind = a.AppointmentTypeFlagAttribute
LEFT JOIN dw.DimTicketStatus ts ON NEW.ticket2_status = ts.TicketStatusTypeID
WHERE hdr.TicketID = NEW.ticket_id;
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
Upvotes: 1