mysql 预写策略wal,在MySQL触发器中使用预准备语句的替代方法

我正在尝试使用以下代码创建一个MySQL插入之前触发器,如果​​我能找到一种方法来执行触发器生成的准备好的语句,它将执行我想要的事情.

是否有其他方法可以从触发器内部执行准备好的语句?谢谢

BEGIN

SET @CrntRcrd = (SELECT AUTO_INCREMENT FROM information_schema.TABLES

WHERE TABLE_SCHEMA=DATABASE()

AND TABLE_NAME='core_Test');

SET @PrevRcrd = @CrntRcrd-1;

IF (NEW.ID IS NULL) THEN

SET NEW.ID = @CrntRcrd;

END IF;

SET @PrevHash = (SELECT Hash FROM core_Test WHERE Record=@PrevRcrd);

SET @ClmNms = (SELECT CONCAT('NEW.',GROUP_CONCAT(column_name

ORDER BY ORDINAL_POSITION SEPARATOR ',NEW.'),'')

FROM information_schema.columns

WHERE table_schema = DATABASE()

AND table_name = 'core_Test');

SET @Query = CONCAT("SET @Query2 = CONCAT_WS(',','",@PrevHash,"','", @CrntRcrd, "',", @ClmNms, ");");

PREPARE stmt1 FROM @Query;

EXECUTE stmt1;

DEALLOCATE PREPARE stmt1;

SET NEW.Hash = @Query2;

END

更新/澄清:数据将存储在下表中.

+------------+-----+------+----------------+

| Record (AI)| ID | Data | HASH |

+------------+-----+------+----------------+

| 1 | 1 | ASDF | =DHFBGKJSDFHBG | (Hash Col 1)

| 2 | 2 | NULL | =UEGFRYJKSDFHB | (Hash Col 1 + Col 2)

| 3 | 1 | VBNM | =VKJSZDFVHBFJH | (Hash Col 2 + Col 3)

| 4 | 4 | TYUI | =KDJFGNJBHMNVB | (Hash Col 3 + Col 4)

| 5 | 5 | ZXCV | =SDKVBCVJHBJHB | (Hash Col 4 + Col 5)

+------------+-----+------+----------------+

在每个插入命令上,表将通过将前一行的哈希值映射到整个新行的CONCAT()上,然后重新哈希整个字符串,从而为该行生成哈希值.这将创建哈希值的运行记录,以用于审核目的/在应用程序的另一部分中使用.

我的约束是必须在INSERT之前完成此操作,因为以后不能再更新行.

更新:我目前正在使用以下代码,直到我找到一种将列名动态传递给CONCAT的方法为止:

BEGIN

SET @Record = (

SELECT AUTO_INCREMENT FROM information_schema.TABLES

WHERE TABLE_SCHEMA=DATABASE()

AND TABLE_NAME='core_Test' #

);

SET @PrevRecrd = @Record-1;

IF (new.ID IS NULL) THEN

SET new.ID = @Record;

END IF;

SET @PrevHash = (

SELECT Hash FROM core_Test #

WHERE Record=@PrevRecrd

);

SET new.Hash = SHA1(CONCAT_WS(',',@PrevHash, @Record,

/* --- UPDATE TABLE COLUMN NAMES HERE (EXCLUDE "new.Record" AND "new.Hash") --- */

new.ID, new.Name, new.Data

));

END

解决方法:

简短的答案是您不能在TRIGGER中使用动态SQL.

我对auto_increment值的查询感到困惑,并为ID列分配了一个值.我不明白为什么您需要设置ID列的值.那不是定义为AUTO_INCREMENT的列吗?数据库将处理分配.

还不清楚您的查询是否保证返回唯一值,尤其是在运行并发插入时. (我尚未测试,因此可能会起作用.)

但是代码很特殊.

您似乎要完成的工作似乎是从最近插入的行中获取列的值.我认为查询触发器定义在同一张表上存在一些限制. (我肯定知道Oracle中有此功能; MySQL可能会更宽松.)

如果我需要做这样的事情,我会尝试这样的事情:

SELECT @prev_hash := t.hash AS prev_hash

FROM core_Test t

ORDER BY t.ID DESC LIMIT 1;

SET NEW.hash = @prev_hash;

但是同样,我不确定这是否可以工作(我需要测试).如果它在简单的情况下起作用,则不能证明它在所有同时插入的情况下,在扩展插入的情况下都一直有效.

我以这种方式编写了查询,以便可以利用ID列上的索引来执行反向扫描操作.如果它不使用索引,我将尝试重写该查询(可能以JOIN形式进行),以获得最佳性能.

SELECT @prev_hash := t.hash AS prev_hash

FROM ( SELECT r.ID FROM core_Test r ORDER BY r.ID DESC LIMIT 1 ) s

JOIN core_Test t

ON t.ID = s.ID

摘自MySQL 5.1参考手册E.1对存储程序的限制

&LT剪断&GT

SQL预准备语句(PREPARE,EXECUTE,DEALLOCATE PREPARE)可以在存储过程中使用,但不能用于存储函数或触发器.因此,存储的函数和触发器不能使用动态SQL(将语句构造为字符串然后执行它们).

&LT /剪断&GT

标签:mysql,prepared-statement,triggers

来源: https://codeday.me/bug/20191012/1902533.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值