如何更改 SQL 服务器而不是删除触发器到 PostgresSQL

How to change SQL Server instead of delete trigger to PostgreSQL

我想在 PostgreSQL 中创建与在 SQL Server 中相同的触发器。

我尝试更改代码以使其正常运行,但出现了很多错误,但未说明问题出在哪里,但不知何故,我设法更改了我的代码,使其可以 运行 但随后调用触发器时出现错误:

relation old doesn't exist

SQL 服务器触发器:

CREATE TRIGGER DeleteUser 
ON users
INSTEAD OF DELETE
AS
BEGIN
    IF EXISTS (SELECT * 
               FROM deleted d
               LEFT JOIN orders as o on o.user_id = d.id
               WHERE o.id IS NOT NULL)
    BEGIN
        ROLLBACK
        RAISERROR('Cannot delete this record: user already ordered something',16,1)
    END
    ELSE
    BEGIN
        DELETE FROM users
        WHERE EXISTS (SELECT * FROM deleted d WHERE d.id = users.id)

        PRINT('Deleted!')
    END
END
GO

Postgres 的改编代码:

函数:

CREATE FUNCTION delete_user()
RETURNS TRIGGER
AS $$
BEGIN
IF EXISTS (
    SELECT * 
    FROM old d
    LEFT JOIN orders as o on o.user_id = d.id
    where o.id is not null
    ) THEN
    RAISE EXCEPTION 'Cannot delete this record: user already ordered something';
ELSE
      DELETE FROM users
      WHERE EXISTS (Select * from deleted d where d.id = users.id);
      RAISE NOTICE 'Deleted!';
END IF;
END;
$$
LANGUAGE plpgsql;

触发器:

CREATE TRIGGER deletion_of_user
    BEFORE DELETE
    ON public.users
    FOR EACH ROW
    EXECUTE PROCEDURE public.delete_user();

您不需要在触发代码中删除。由于它是一个 before 触发器,只需返回 old 记录就足以使删除发生。

您创建了一个行级别触发器(SQL服务器没有),所以old记录只是一行,你不能 select 从它。只需在 SELECT 语句的 WHERE 子句中使用它即可。

CREATE FUNCTION delete_user()
RETURNS TRIGGER
AS $$
BEGIN
IF EXISTS (
    SELECT * 
    FROM orders as o 
    where o.user_id = old.id; --<< no need for a join
    ) THEN
    RAISE EXCEPTION 'Cannot delete this record: user already ordered something';
ELSE
    RAISE NOTICE 'Deleted!';
    return old; --<< tell Postgres to continue with the delete
END IF;
END;
$$
LANGUAGE plpgsql;

但是(误)为此使用触发器是错误的方法(在 Postgres 中和在 SQL 服务器中一样)。您应该从引用用户 table 的订单 table 中声明一个外键,这同样可以防止删除 - 并且可能更有效。