我有一个表测试的触发器函数,它具有以下代码片段:
IF TG_OP='UPDATE' THEN
IF OLD.locked > 0 AND
( OLD.org_id <> NEW.org_id OR
OLD.document_code <> NEW.document_code OR
-- other columns ...
)
THEN
RAISE EXCEPTION 'Message';
-- more code
Run Code Online (Sandbox Code Playgroud)
所以我静态检查所有列的新值及其先前的值以确保完整性.现在,每当我的业务逻辑发生变化并且我必须在该表中添加新列时,我每次都必须修改此触发器.我认为如果不知何故我可以动态检查该表的所有列,而不显式输入其名称会更好.
怎么做到呢?
我有一个要修改的MySQL触发器。唯一的变化是在触发器主体中。
是否足以更新ACTION_STATEMENTColumn INFORMATION_SCHEMA.TRIGGERS?这是更新触发器的正确方法吗?具体来说,我正在寻找这样做可能引起的任何问题。
我是MS-SQL的常规用户,但现在正在开发一个以mysql作为后端的项目.
请告诉我在mysql中是否存在这样的插入/删除表(魔术表),我可以在触发器内或普通查询中使用.
我的环境是Oracle 11g.我有一个表T_IMG,其列是图像blob,图像标识符,图像的哈希计算为SHA256.我希望每次在T_IMG表中插入或更新行时计算图像哈希并将其插入到T_IMG表中.为此,我在T_IMG表上使用插入或更新的before触发器,但是我很难访问触发器内的图像blob列.
CREATE TABLE TEST.T_IMG
(
IDN VARCHAR2(18 BYTE) NOT NULL,
IMG BLOB NOT NULL,
IMGHASH VARCHAR2(128 BYTE)
);
Run Code Online (Sandbox Code Playgroud)
字符串和blob的SHA256哈希值由以下代码计算,该代码基于Sean Stuber在http://seanstuber.wordpress.com/2012/03/22/using-java-to-extend-dbms_crypto/上的示例
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED sha2 AS
import java.security.MessageDigest;
import oracle.sql.*;
public class sha2
{
public static oracle.sql.RAW get_digest_string( String p_string, int p_bits ) throws Exception
{
MessageDigest v_md = MessageDigest.getInstance( "SHA-" + p_bits );
byte[] v_digest;
v_digest = v_md.digest( p_string.getBytes( "UTF-8" ) );
return RAW.newRAW(v_digest);
}
public static oracle.sql.RAW get_digest_blob( oracle.sql.BLOB p_blob, int …Run Code Online (Sandbox Code Playgroud) 使用MSSQL2008.
我有两张桌子.
TableResource
-------------
ID [bigint]
Attribute1 [int]
Attribute2 [int]
Attribute3 [int]
VersionId [uniqueidentifier]
Run Code Online (Sandbox Code Playgroud)
和
TableResourceHistory
--------------------
ID [bigint]
Attribute3History [int]
HistoryDate [datetime]
VersionId [uniqueidentifier]
Run Code Online (Sandbox Code Playgroud)
我有一个instead of update需要完成两件事的触发器:
TableReResource.Attribute3"已更改,则使用"旧"Attribute3值将历史记录写入历史表,并且还修改表的" TableResource.VersionId"字段TableResource.TableReResource.Attribute3" 没有变化,那么只需通过UPDATE.这是我到目前为止所做的,但是我无法想出相等比较来触发历史记录日志.
CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId] ON [dbo].[TableResources]
INSTEAD OF UPDATE
AS
SET NOCOUNT ON;
BEGIN
-- ?? IF inserted.Attribute3 = deleted.Attribute3
-- ?? THEN we just pass the UPDATE through
UPDATE [TableResources]
SET
VersionId = inserted.VersionId,
Attribute1 = inserted.Attribute1,
Attribute2 …Run Code Online (Sandbox Code Playgroud) 我创建了一个调用这样的程序集的Trigger:
CREATE TRIGGER Testrigger ON STATION
FOR INSERT
AS EXTERNAL NAME assemblytest.[WriteTimeInfile.Program].Testrigger
Run Code Online (Sandbox Code Playgroud)
该程序集中的.NET代码执行如下操作:
namespace WriteTimeInfile
{
public class Program
{
[SqlTrigger(Name = @"Testrigger", Target = "[dbo].[STATION]", Event = "FOR INSERT, UPDATE, DELETE")]
public static void Testrigger()
{
File.AppendAllText(@"C:\Users\Vivien\date.txt",
DateTime.Now.ToString() + Environment.NewLine);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够作为参数传递创建的行或更新的行,如下所示:
CREATE TRIGGER Testrigger ON STATION
AFTER INSERT
AS
EXTERNAL NAME assemblytest.[WriteTimeInfile.Program].Testrigger (STATION.ID)
Run Code Online (Sandbox Code Playgroud)
我在StackOverflow上发现了一个7年的主题,它告诉我们无法将参数传递给CLR程序集.
我在问最近的SQL Server版本是否可行.
你知道是否有办法,如果是的话怎么办?
在触发器内部,我试图遍历表格上的所有列,并将新值与旧值进行比较.这是我到目前为止:
CREATE OR REPLACE TRIGGER "JOSH".TEST#UPD BEFORE
UPDATE ON "JOSH"."TEST_TRIGGER_TABLE" REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW
declare
oldval varchar(2000);
newval varchar(2000);
begin
for row in (SELECT column_name from user_tab_columns where table_name='TEST_TRIGGER_TABLE') loop
execute immediate 'select :old.'||row.column_name||' from dual' into oldval;
execute immediate 'select :new.'||row.column_name||' from dual' into newval;
--Do something here with the old and new values
end loop;
end;
Run Code Online (Sandbox Code Playgroud)
触发器编译,但是当触发器触发时,我得到:
ORA-01008:并非所有变量都绑定
在第一次执行立即因为它期望值为:old. :old并且:new已经被定义为触发器的一部分,但看起来执行立即数不能看到那些变量.
有没有办法动态迭代触发器中的列值?
几周前我刚刚开始学习 SQL,我正在尝试制作一个触发器,如果插入的值小于 10,它会将插入的值更改为 10。我现在搜索了 4h,我找到了很多答案,但没有很好(对我来说)。我真的不明白问题出在哪里。这是代码:
CREATE OR REPLACE TRIGGER NumberOfBooks
BEFORE INSERT
ON Book
FOR EACH ROW
BEGIN
IF new.nobook < 10
THEN
SET new.nobook = 10;
END IF;
END;
Run Code Online (Sandbox Code Playgroud) 我需要在 Node 和 PostgreSQL 中使用 Sequelize Migration 在我的一张表上创建触发器。我还没有找到足够的相关文档。
目前我使用的是sequelize版本3.23并且非常熟悉PostgreSQL触发器,但无法找到有关触发器迁移的任何内容。
我正在关注sequelize 网站上提供的与迁移相关的文档:
module.exports = {
up: function(queryInterface, Sequelize) {
// create trigger
},
down: function(queryInterface, Sequelize) {
// remove trigger
}
}
Run Code Online (Sandbox Code Playgroud)
希望我能快速解决这个问题。提前致谢:)
我目前正在使用 Oracle 11g。根据我的要求,我需要将前 4000 个(最大限制)字符存储到我的变量(在触发器中使用)。
为此,我正在使用 VarName = SUBSTR 函数 (VarName, 1, 4000),但它似乎没有存储任何内容(我正在传递 '111...'(要存储的 4096 个字符),我想从中存储 (' 111...') 仅限前 4000 个字符)。
它适用于 4 个字符,但不适用于最大限制。我尝试将长度设为 3999、3000,但没有任何效果。
请仔细研究一下,并为此建议我一些解决方案。
(*注意:我无法将变量类型从 varchar 更改为 clob,因为该列已经拥有数百万个遗留数据。)
*修改:我尝试使用 Substr 长度 2048,它正在工作,但是一旦我向 substr 提供 2049 个字符,它再次变为 null。但在数据类型字段值被定义为 VARCHAR2(4000 CHAR)。
database-trigger ×10
oracle ×4
plsql ×3
mysql ×2
postgresql ×2
sql-server ×2
t-sql ×2
triggers ×2
.net ×1
blob ×1
dynamic ×1
node.js ×1
oracle11g ×1
oracle11gr2 ×1
plpgsql ×1
sequelize.js ×1
sha2 ×1
sql ×1
sqlclr ×1