函数中 table 的子句条目中缺少 PostgreSQL
PostgreSQL missing from clause entry for table in function
我有以下函数处理插入或更新时的触发器:
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;
我收到错误:missing FROM-clause entry for table "d"
我想这可能与我在查询中没有在技术上使用的 db1.tickets
table 有某种关系。我试过去掉那个位,然后用 WHERE d.date_key = NEW.ticket_date
做 FROM dw.DimDate
,这给出了同样的错误。
SO 上有很多这类问题,但我还没有找到一个解决这个特定场景的问题,因为我觉得它与它在这个触发函数内部有关。
函数是从这里调用的:
CREATE TRIGGER trg_tickets AFTER INSERT OR UPDATE ON db1.tickets
FOR EACH ROW EXECUTE PROCEDURE ticketChangeFunc();
我还想知道是否使用 ON CONFLICT UPDATE
子句在找到匹配项时更新每一行,而不管值是否不同?这对性能有影响吗?如果有,有没有办法检查每个字段是否相等,如果没有差异则什么也不做?
对于那些将来可能碰巧 运行 的人,我的解决方案是向函数添加一个条件,并与更新分开处理插入:
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;
我有以下函数处理插入或更新时的触发器:
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;
我收到错误:missing FROM-clause entry for table "d"
我想这可能与我在查询中没有在技术上使用的 db1.tickets
table 有某种关系。我试过去掉那个位,然后用 WHERE d.date_key = NEW.ticket_date
做 FROM dw.DimDate
,这给出了同样的错误。
SO 上有很多这类问题,但我还没有找到一个解决这个特定场景的问题,因为我觉得它与它在这个触发函数内部有关。
函数是从这里调用的:
CREATE TRIGGER trg_tickets AFTER INSERT OR UPDATE ON db1.tickets
FOR EACH ROW EXECUTE PROCEDURE ticketChangeFunc();
我还想知道是否使用 ON CONFLICT UPDATE
子句在找到匹配项时更新每一行,而不管值是否不同?这对性能有影响吗?如果有,有没有办法检查每个字段是否相等,如果没有差异则什么也不做?
对于那些将来可能碰巧 运行 的人,我的解决方案是向函数添加一个条件,并与更新分开处理插入:
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;