假设我在行更新上执行以下函数:
CREATE OR REPLACE FUNCTION versioned_update()
RETURNS TRIGGER AS $$
DECLARE
sql TEXT;
BEGIN
sql := 'INSERT INTO backup_table VALUES (OLD)';
EXECUTE sql;
END;
$$ language 'plpgsql';
Run Code Online (Sandbox Code Playgroud)
上面的示例不起作用,因为OLD在该执行上下文中未知。所以我尝试了类似的方法:
sql := format('INSERT INTO backup_table VALUES (%L)', OLD);
Run Code Online (Sandbox Code Playgroud)
和
sql := format('INSERT INTO backup_table VALUES (%L)', (OLD));
Run Code Online (Sandbox Code Playgroud)
和
sql := format('INSERT INTO backup_table VALUES (%L)', (OLD.*));
Run Code Online (Sandbox Code Playgroud)
一切都没有任何运气。
这个问题是我正在研究的一个更大的触发因素的一部分。孤立来看,这没有多大意义,但说明了问题。
我有这 3 个表:
构造函数员工
EID (员工 ID)作为主键和其他键。项目
PID 作为主键和其他键。项目建设者员工
PID并EID作为其他表的外键。每个ConstructorEmployee可以在几个Projects. 我需要创建一个触发器,如果项目已被删除,我需要删除所有ConstructorEmployee 该工作仅在这个项目上。我需要从ConstructorEmployee表中删除它们。
我正在研究 SQL Server 2017。
我正在尝试编写 Postgres 触发器以在插入或更新新行之前取消嵌套数组字段。例如
SELECT
unnest(something)
FROM NEW
Run Code Online (Sandbox Code Playgroud)
但是,这似乎会导致错误:
关系“新”不存在
如何使用触发器函数内的 NEW 行,以允许我取消嵌套数组字段以进行进一步处理?
创建表语句
以下是表结构的示例:
CREATE TABLE parent_table (
id uuid NOT NULL,
jsonb_array_field jsonb[] NOT NULL DEFAULT '{}'::jsonb[],
CONSTRAINT "parent_table_pkey" PRIMARY KEY (id),
);
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE many_to_one_table (
id serial primary key,
parent_table_id uuid references parent_table(id),
subfield_a text,
subfield_a text
);
Run Code Online (Sandbox Code Playgroud)
触发功能
下面是 TRIGGER 函数的本质:
CREATE OR REPLACE FUNCTION unnest_and_normalize_json() RETURNS TRIGGER AS
$body$
begin
if NEW.jsonb_array_field is null then
raise exception 'jsonb_array_field is null';
else
insert into
many_to_one_table(subfield_a, subfield_b) …Run Code Online (Sandbox Code Playgroud) 我非常了解触发器背后的想法、如何以及何时使用它们。
我还看到了触发器的实际用途FOR EACH ROW。
但我找不到何时使用触发器的具体示例FOR STATEMENT。我能用它做什么?
谁能给我一个现实生活中使用它的例子吗?
我特意创建了这个例子来代表我的问题。
我创建了这样的表:
CREATE TABLE a
(
id INT
)
Run Code Online (Sandbox Code Playgroud)
然后我像这样创建了 2 个AFTER TRIGGER:
CREATE TRIGGER insert_a
ON a AFTER INSERT
AS
BEGIN
INSERT INTO a VALUES (1)
END
GO
CREATE TRIGGER insert_a2
ON a AFTER INSERT
AS
BEGIN
INSERT INTO a VALUES(2)
END
GO
Run Code Online (Sandbox Code Playgroud)
之后我插入到表中:
INSERT INTO a VALUES (0)
Run Code Online (Sandbox Code Playgroud)
我得到了结果:
消息 217,级别 16,状态 1,过程 insert_a2,第 5 行 [批处理起始行 0]。
超出最大存储过程、函数、触发器或视图嵌套级别(限制为 32)。
我认为这里存在周期性情况。触发器内部的插入,一次又一次地触发触发器。那会发生吗?
我想知道里面发生了什么?
有没有办法解决这个问题,但仍然保持完整的 2 AFTER INSERT触发器?
疯狂的情况。
我想在 Postgresql 中使用触发器调用存储过程。是否可以?
这是一个例子:
create table foo(n int primary key, n1 int);
create or replace procedure set_column_value(value int)
language plpgsql
:as $$
begin
update foo
set n1 = id
commit;
end;$$
Run Code Online (Sandbox Code Playgroud)
触发器类似于:在 foo 上插入或更新后,调用存储过程 set_column_value(new.n)
我有一个通过创建以下内容来保护我的数据库管理员帐户的想法:
但是,这仍然只是一个想法,我不知道这是否可行,您知道是否有人尝试过吗?
任何链接或参考资料。
我的灵感来自我的朋友,他在登录工作站时挂在脖子上的一个小设备中生成了一个密钥,有谁知道这个安全程序叫什么?
可能出现的限制或问题是什么?(服务器崩溃/重启)
谢谢!
我有以下完美运行的 DML 语句,我试图将它变成触发器,但它不起作用。
DML 语句
UPDATE HOLIDAY_RESERVATION R SET SUBTOTAL =
NVL((SELECT F.FLI_PRICE FROM FLIGHT F WHERE F.FLI_ID = R.IN_FLIGHT_ID), 0) * NVL(R.IN_FLIGHT_SEATS_NO,0) +
NVL((SELECT F.FLI_PRICE FROM FLIGHT F WHERE F.FLI_ID = R.OUT_FLIGHT_ID), 0)* NVL(R.OUT_FLIGHT_SEATS_NO,0) +
NVL((SELECT AC.ACC_PRICEPN FROM ACCOMMODATION AC WHERE AC.ACC_ID = R.ACC_ID), 0);
Run Code Online (Sandbox Code Playgroud)
触发语句
CREATE OR REPLACE TRIGGER HR_SUBTOTAL
BEFORE INSERT OR UPDATE ON HOLIDAY_RESERVATION
FOR EACH ROW
BEGIN
SELECT
NVL((SELECT F.FLI_PRICE FROM FLIGHT F WHERE F.FLI_ID = :NEW.IN_FLIGHT_ID), 0) * NVL(R.IN_FLIGHT_SEATS_NO,0) +
NVL((SELECT F.FLI_PRICE FROM FLIGHT …Run Code Online (Sandbox Code Playgroud) 我来自 Oracle/PostgreSQL 背景,很难应对 SQL Server 触发器实现的限制。
datetime如果不同列的值发生变化,我想更新两个不同的列。这是为了记录该行的两个特定状态变化。
现在 SQL Server 既没有行级触发器,也没有before update触发器。所以我的理解是,我需要加入插入和删除以找出是否发生了状态更改以及发生了哪些状态更改,然后对正在更新的表再次运行“常规”更新。
我的触发器目前看起来像这样:
create trigger ord_status_history_trigger
on jobs
AFTER UPDATE
AS
IF ( UPDATE(order_status) )
BEGIN
update jobs
set transfercomplete = case
when o.order_status = 'initial' and n.order_status = 'sent' then current_timestamp
else n.transfercomplete
end,
installcomplete = case
when o.order_status = 'delivered' n.order_status = 'installed' then current_timestamp
else n.installcomplete
end
from inserted n
join deleted o on o.jobid = n.jobid
join jobs aj on aj.jobid = n.jobid; …Run Code Online (Sandbox Code Playgroud) 我已经转换的表有一个小问题,它曾经是 MyISAM,我现在已经把它变成了 InnoDB 表。
原始结构:
id varchar(15),
seqno int(11) auto increment
Joint PK index on the above 2 fields
Run Code Online (Sandbox Code Playgroud)
新结构:
auto_id INT (11) auto increment,
id varchar(15),
seqno int(11)
Run Code Online (Sandbox Code Playgroud)
原始结构在 id 和 seqno 上有一个联合 PK,seqno 会为每个唯一的 id 值自动递增。然后它会在我的 Web 应用程序中返回 seqno 作为 last_insert_id。
使用新的 innodb 结构,因为 innodb 不支持联合主键,我不得不添加一个 auto_id,它现在具有自动增量。
然后我实现了一个触发器来生成每个 id 值的唯一序列号。我的问题是如何设置自动增量 id 以便它返回代替 auto_id 值?当我插入到 my_table 中时,将调用此触发器,以便它可以计算要插入的下一个 seqno 值。
DROP TRIGGER IF EXISTS `innodb_seqno_trigger`;
//
CREATE TRIGGER `innodb_seqno_trigger` BEFORE INSERT ON `my_table`
FOR EACH ROW BEGIN
SET @newseqno = …Run Code Online (Sandbox Code Playgroud) trigger ×10
postgresql ×3
mysql ×2
sql-server ×2
encryption ×1
innodb ×1
insert ×1
myisam ×1
oracle ×1
plsql ×1
security ×1
subquery ×1