标签: database-trigger

使用`BEFORE INSERT`触发器更改传入数据的数据类型以匹配PostgreSQL中的列数据类型

我有一个postgres表,列C有一个类型T.人们将使用COPY将数据插入此表.但是有时他们会尝试为不属于T类型的C插入一个值,但是我有一个postgres函数可以将值转换为T.

我正在尝试BEFORE INSERT在表上写一个触发器,它将在数据上调用此函数,以便我可以确保没有插入类型错误.然而,它似乎不起作用,我在尝试插入数据时遇到错误,即使触发器在那里.

在我花太多时间调查之前,我想知道这是否可行.我可以以这种方式使用触发器来更改传入数据的类型吗?

我希望这个在postgresql 9.3上运行,但我注意到postgres 9.5上的错误和无效触发器.

database postgresql triggers type-conversion database-trigger

8
推荐指数
2
解决办法
1405
查看次数

如何创建修改分区 Postgres 表中记录的触发器?

我有一个带有触发器的表,每当记录更改时都会更新“修改的”时间戳。我用 BEFORE 触发器做到了:

CREATE OR REPLACE FUNCTION update_modified()
  RETURNS trigger AS
$$
BEGIN
  NEW.modified = now();
  RETURN NEW;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER contact_update_modified
  BEFORE UPDATE
  ON contacts
  FOR EACH ROW
  EXECUTE PROCEDURE update_modified();
Run Code Online (Sandbox Code Playgroud)

然后我对表进行分区,当我尝试添加触发器时,我得到:

ERROR:  "contacts" is a partitioned table
DETAIL:  Partitioned tables cannot have BEFORE / FOR EACH ROW triggers.
SQL state: 42809
Run Code Online (Sandbox Code Playgroud)

如果我将其更改为 AFTER 触发器,它不会更新修改的字段(这是有道理的)。

如果我手动将触发器添加到每个子分区表,它似乎确实有效。我可以做到这一点,但并不理想。有没有更好的办法?

postgresql triggers partitioning database-partitioning database-trigger

8
推荐指数
1
解决办法
5949
查看次数

无法创建删除触发器,因为表具有带有级联DELETE的FOREIGN KEY

我正在尝试创建一个删除触发器.我有这个名为Nemanet_Navigation的导航表.该表有自己的外键,但在选择INSERT和UPDATE规范中的表的关系时 - 删除规则NO Action.所以我不选择Cascading.然后我有这个触发器:

CREATE TRIGGER Del_Nemanet_Navigation ON Nemanet_Navigation 
  INSTEAD OF DELETE
AS  

CREATE TABLE #Table(
    Nav_ID uniqueidentifier
    )
    INSERT INTO #Table (Nav_ID)
    SELECT Nav_ID
    FROM deleted

    DECLARE @C uniqueidentifier
    SET @c = 0

    WHILE @C <> (SELECT COUNT(Nav_ID) FROM #Table) BEGIN
        SELECT @c = COUNT(Nav_ID) FROM #Table

        INSERT INTO #Table (Nav_ID)
        SELECT Nemanet_Navigation.Nav_ID
        From Nemanet_Navigation
        LEFT OUTER JOIN #Table ON Nemanet_Navigation.Nav_ID = #Table.Nav_ID
        WHERE   Nemanet_Navigation.Nav_pID IN (SELECT Nav_ID FROM #Table)
        AND     #Table.Nav_ID IS NULL
    END

    DELETE  Nemanet_Navigation
    FROM    Nemanet_Navigation …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server database-trigger

7
推荐指数
1
解决办法
2347
查看次数

行创建和最后修改的时间戳

我需要跟踪一行插入数据库的时间以及上次修改的时间.

我试图创建两个单独的列,并使用CURRENT_TIMESTAMP:

create table def (
  id int, 
  creation timestamp 
    default CURRENT_TIMESTAMP, 
  modification timestamp 
    on update CURRENT_TIMESTAMP
);
Run Code Online (Sandbox Code Playgroud)

但是,这产生了一个错误:

错误1293(HY000):表定义不正确; 在DEFAULT或ON UPDATE子句中只能有一个TIMESTAMP列和CURRENT_TIMESTAMP

做这个的最好方式是什么?

我在考虑存储过程,但寻找标准解决方案.我也关注访问权限 - 因为很少有程序/事情应该能够触及时间戳.


虽然我更喜欢MySQL的答案,但其他RDBMS的解​​决方案也很受欢迎!

mysql sql timestamp database-trigger mysql-error-1293

7
推荐指数
1
解决办法
9836
查看次数

使用PERFORM CTE查询Postgres plpgsql

我试着在下面的代码示例中模拟我的问题.在下面的代码中,我正在执行select * from test一个过程.我们知道,我们必须使用perform关键字.这非常有效:

perform * from test;
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试将该简单查询重写为CTE,我无法使其正常工作.我收到语法错误.

with test_as_cte as(select * from test) perform * from test_as_cte;
Run Code Online (Sandbox Code Playgroud)

这可能吗?什么是正确的语法?我尝试了几种替代方案并通过文档,但到目前为止没有任何成功.

(请注意,这只是解释我的问题的一个例子.我知道查询没有任何意义.)

create table test
(
    key int primary key  
);

create function test() returns trigger as
$$
begin
    raise notice 'hello there';
    -- this does work
    perform * from test;
    -- this doesn't work
    with test_as_cte as(select * from test) perform * from test_as_cte;
    return new;
end;
$$
language plpgsql;

create trigger test after insert on …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql common-table-expression database-trigger

7
推荐指数
1
解决办法
944
查看次数

Postgres:在 FOREIGN TABLE 上触发

我想在我的数据库中使用postgres_fdw和存放 a FOREIGN TABLE。是否可以在本地服务器上定义一个触发器FOREIGN TABLE来识别INSERT远程服务器上的事件。如果是这样,请提供一个例子。


数据流:

  1. 将数据插入远程服务器上的表中。
  2. 识别触发触发器的本地服务器的外部表上的插入。
  3. 触发器函数将数据写入其他表。
  4. 写入成功后,回发到外部表

想法作为一个粗略的图表:


未报告错误,但对 table_b 的写入似乎不成功。

这是我尝试过的:

CREATE FOREIGN TABLE x.table_a   -- note the foreign table is in a different schema than the local table
( id        BIGINT           NOT NULL                   
, data_ts   TIMESTAMPTZ      DEFAULT CURRENT_TIMESTAMP
, xchg_ts   TIMESTAMPTZ      DEFAULT NULL
)
SERVER remote_server
OPTIONS (schema_name 'schema_a', table_name 'table_a')
;

CREATE TABLE y.table_b
( xchg_id    BIGINT
, error_msg  TEXT DEFAULT NULL
);
Run Code Online (Sandbox Code Playgroud)
CREATE OR REPLACE FUNCTION …
Run Code Online (Sandbox Code Playgroud)

postgresql database-trigger postgres-fdw

7
推荐指数
1
解决办法
1796
查看次数

是否可以在网页上显示触发错误消息?

我在一定条件下有触发器,如果​​条件:false发生错误。我应该在数据库触发器中显示该错误消息,HTML以便通知用户!

CREATE TRIGGER check_trigger BEFORE INSERT ON your_table
FOR EACH ROW
BEGIN        
    IF (NEW.name = NEW.firstname) THEN
        SIGNAL SQLSTATE '45000' 
            SET MESSAGE_TEXT = 'same names error. Insertion canceled';
    END IF;
END
Run Code Online (Sandbox Code Playgroud)

如何显示SET MESSAGE_TEXT=""到网页?如果不可能通过其他方式

html php mysql database-trigger error-messaging

7
推荐指数
1
解决办法
88
查看次数

仅订阅者触发器

有两个服务器.首先是生产中的ERP系统.第二个是用于重度分析查询的BI服务器.我们每天通过备份更新BI服务器.但是,这还不够,有些用户希望比第二天更频繁地看到他们的数据更改.除了要求备份或复制之外,我无法访问ERP服务器并且无法执行任何操作.

在开始要求复制之前.我想了解是否可以使用订阅者触发器来处理并非所有数据,而是更改.有一个ETL过程可以更快地进行一些查询(索引,转换等).触发器应该可以解决问题,但我找不到在订户端使用它们的方法.ERP系统不允许在数据库级别进行任何更改.因此,订阅者数据库似乎适用于触发器(它们不会影响ERP服务器性能).尽管如此,我找不到一种方法来设置它们.处理所有数据是一个疯狂的开销.

使用案例:简化示例,比方说,我们有两个复制表:

+------------+-------------+--------+
|     dt     | customer_id | amount |
+------------+-------------+--------+
| 2017-01-01 |           1 |    234 |
| 2017-01-02 |           1 |    123 |
+------------+-------------+--------+

+------------+-------------+------------+------------+
| manager_id | customer_id | date_from  |  date_to   |
+------------+-------------+------------+------------+
|          1 |           1 | 2017-01-01 | 2017-01-02 |
|          2 |           1 | 2017-01-02 |       null |
+------------+-------------+------------+------------+
Run Code Online (Sandbox Code Playgroud)

我需要将它们转换为以下索引表:

+----------+-------------+------------+--------+
|  dt_id   | customer_id | manager_id | amount |
+----------+-------------+------------+--------+
| 20170101 |           1 |          1 |    234 |
| …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server replication triggers database-trigger

6
推荐指数
1
解决办法
744
查看次数

在创建触发器时 FUNCTION 处或附近的 PostgreSQL 语法错误

我在运行 Ubuntu 服务器 18.04 的新机器上安装了 postgresql 和 postgresql-plpython-10(使用 apt),并且我已经将 Postgresql 数据库(使用 提取pg_dumpall)从另一台机器恢复到新机器(Linux)上。

我检查了数据库中存在trackspreadsheetnztplpy函数并且存在表nztgsheet。我在旧机器上重新运行了这个功能,它运行得很好。我查plpythonu安装使用psql的命令在新机器上:\dL

SQL 错误:

错误:“FUNCTION”第 1 行或附近的语法错误:...H ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) EXECUTE FUNCTION t... ^

在声明中: CREATE TRIGGER trackspreadsheetnzt AFTER UPDATE ON nztgsheet FOR EACH ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) EXECUTE FUNCTION trackspreadsheetnztplpy();

我希望触发器函数可以工作,但它会引发语法错误。

postgresql database-trigger

6
推荐指数
1
解决办法
2469
查看次数

从 mysql 中的触发器或存储过程调用 REST API?

我想POST在 Windows 上的 mysql 服务器中的存储过程或触发器的方法中调用 rest api 。

如何仅使用 MySQL 执行此操作?

mysql rest json stored-procedures database-trigger

5
推荐指数
2
解决办法
5825
查看次数