插入触发器生成的新列值
insert into new column values generated from trigger
我想创建一个触发器,它根据 table 中其他几个列的值生成一个 18 位代码。
R-MU-WEST-RJS-9697
所以基本上我的最后 4 位代码是 STORE_CODE
,我想根据它比较并插入那个 18 位代码,名为 CODE_18DIGIT
[= 的列17=]
下面是生成代码
的select
语句
SELECT 'R-'
|| CASE
WHEN INSTR (TRIM (r.state), ' ') > 1
THEN
SUBSTR (r.state, 1, 1)
|| SUBSTR (r.state, INSTR (r.state, ' ') + 1, 1)
ELSE
UPPER (SUBSTR (r.state, 1, 2))
END
|| '-'
|| UPPER (SUBSTR (r.zone_name, 1, 4))
|| '-'
|| r.format_code
|| '-'
|| SUBSTR (r.store_code, 1, 4)
FROM tbl_rrsoc_store_info r
WHERE r.ISACTIVE = 'Y';
和 tbl_rrsoc_store_info
的 table 描述如下
Name Null Type
--------------------------- -------- --------------
RRSOC_ID NOT NULL NUMBER
STORE_CODE NOT NULL NVARCHAR2(55)
STATE NVARCHAR2(55)
CITY NVARCHAR2(55)
CODE_18DIGIT NVARCHAR2(18)
在架构上,这不是一个特别好的设计。您通过存储冗余数据违反了规范化的基本规则。仅创建一个计算代码的视图或将计算列添加到 table 会更不令人反感。但听起来您已经决定要使用 trigger-based 解决方案。
为简单起见,我将创建一个函数(请注意,您发布的代码引用了您发布的 table 定义中不存在的多个列。我的猜测是这些列存在但被省略了来自您的 table 定义,但也许您更改了查询或 table 定义中的列名,而没有更改其他列名。
create or replace function make_18digit_code(
p_state tbl_rrsoc_store_info.state%type,
p_zone_name tbl_rrsoc_store_info.zone_name%type, -- Note that your table definition doesn't include this column
p_format_code tbl_rrsoc_store_info.format_code%type, -- Or this column
p_store_code tbl_rrsoc_store_info.store_code%type
)
return tbl_rrsoc_store_info.code_18digit%type
is
begin
return 'R-' ||
CASE
WHEN INSTR (TRIM (p_state), ' ') > 1
THEN
SUBSTR (p_state, 1, 1)
|| SUBSTR (p_state, INSTR (p_state, ' ') + 1, 1)
ELSE
UPPER (SUBSTR (p_state, 1, 2))
END
|| '-'
|| UPPER (SUBSTR (p_zone_name, 1, 4))
|| '-'
|| p_format_code
|| '-'
|| SUBSTR (p_store_code, 1, 4);
end;
然后你可以简单地调用触发器中的函数
create or replace trigger trg_generate_code
before insert or update on tbl_rrsoc_store_info
for each row
begin
:new.code_18digit := make_18digit_code( :new.state,
:new.zoe_name,
:new.format_code,
:new.store_code );
end;
我想创建一个触发器,它根据 table 中其他几个列的值生成一个 18 位代码。
R-MU-WEST-RJS-9697
所以基本上我的最后 4 位代码是 STORE_CODE
,我想根据它比较并插入那个 18 位代码,名为 CODE_18DIGIT
[= 的列17=]
下面是生成代码
的select
语句
SELECT 'R-'
|| CASE
WHEN INSTR (TRIM (r.state), ' ') > 1
THEN
SUBSTR (r.state, 1, 1)
|| SUBSTR (r.state, INSTR (r.state, ' ') + 1, 1)
ELSE
UPPER (SUBSTR (r.state, 1, 2))
END
|| '-'
|| UPPER (SUBSTR (r.zone_name, 1, 4))
|| '-'
|| r.format_code
|| '-'
|| SUBSTR (r.store_code, 1, 4)
FROM tbl_rrsoc_store_info r
WHERE r.ISACTIVE = 'Y';
和 tbl_rrsoc_store_info
的 table 描述如下
Name Null Type
--------------------------- -------- --------------
RRSOC_ID NOT NULL NUMBER
STORE_CODE NOT NULL NVARCHAR2(55)
STATE NVARCHAR2(55)
CITY NVARCHAR2(55)
CODE_18DIGIT NVARCHAR2(18)
在架构上,这不是一个特别好的设计。您通过存储冗余数据违反了规范化的基本规则。仅创建一个计算代码的视图或将计算列添加到 table 会更不令人反感。但听起来您已经决定要使用 trigger-based 解决方案。
为简单起见,我将创建一个函数(请注意,您发布的代码引用了您发布的 table 定义中不存在的多个列。我的猜测是这些列存在但被省略了来自您的 table 定义,但也许您更改了查询或 table 定义中的列名,而没有更改其他列名。
create or replace function make_18digit_code(
p_state tbl_rrsoc_store_info.state%type,
p_zone_name tbl_rrsoc_store_info.zone_name%type, -- Note that your table definition doesn't include this column
p_format_code tbl_rrsoc_store_info.format_code%type, -- Or this column
p_store_code tbl_rrsoc_store_info.store_code%type
)
return tbl_rrsoc_store_info.code_18digit%type
is
begin
return 'R-' ||
CASE
WHEN INSTR (TRIM (p_state), ' ') > 1
THEN
SUBSTR (p_state, 1, 1)
|| SUBSTR (p_state, INSTR (p_state, ' ') + 1, 1)
ELSE
UPPER (SUBSTR (p_state, 1, 2))
END
|| '-'
|| UPPER (SUBSTR (p_zone_name, 1, 4))
|| '-'
|| p_format_code
|| '-'
|| SUBSTR (p_store_code, 1, 4);
end;
然后你可以简单地调用触发器中的函数
create or replace trigger trg_generate_code
before insert or update on tbl_rrsoc_store_info
for each row
begin
:new.code_18digit := make_18digit_code( :new.state,
:new.zoe_name,
:new.format_code,
:new.store_code );
end;