2011-08-09 46 views
2

我正在开发一个C系统,它将更新提交到MySQL数据库。客户端并不总是在线,因此当服务器不可访问时,应用程序会将执行的SQL命令保存到* .sql中。MySQL在当前会话期间为所有INSERTS设置字段值

我想添加一个名为late_commit来使用,所以我会知道,那些被插入后,当恢复连接的数据库中的表布尔字段的。

我可以改变程序中的编程逻辑,在插入查询中包含late_commit字段,但我宁愿让它的默认值为false,并且不知何故只有在.sql文件为真时才将它设置为true执行。

我想插入alter语句插入,但这似乎有点笨拙,并会提供较差的性能。

我从来没有使用触发器,但从我看到在这个SO question他们可以工作。但是,它们看起来并不是会话的临时或本地会话,这会干扰来自其他客户端的并发插入。

你有什么想法,你怎么做/会这样做?不一定是使用的查询,而是应用最好的技术/方法。

编辑: 我认为一个解决方案,如果没有其他出现,可能会创建一个临时表具有相同的结构和默认为true,插入数据到它,然后复制到主表。

通知: 我已经添加了一些我找到的方法的答案。我仍然在寻找永久的解决方案。所以请如果你知道如何做得更好请评论或回答。谢谢!

+0

你可以使用预处理语句?我们强烈建议对多个插件,你可以在新的字段的值设置为TRUE;。 – Dor

+0

@Dor我可以使用预处理语句,总是用Java做的,但我是一个有点所有绑定语句,它需要在C API不堪重负。但请记住,如果我准备声明,我将不能执行它,因为那时有一个网络故障,也许有可能提取准备好的声明而不执行它,但我会检查api。 - 这是客户端无法连接到服务器的原因,这就是为什么我想将这些语句保存到一个sql文件中,一旦连接恢复,系统将在稍后执行。 –

回答

0

我想我会离开这里到目前为止我发现的是为了回答这个问题。

正如问题中所述,我最好看到一个只有sql方法,这避免了使用注入器。 准备好的语句无法正常工作,因为它们需要连接到可能不在首位的数据库。


IFNULL()解决方案:

我倾向于使用我想出了使用MySQL的IFNULL语句解决方案,它通过设置一个局部变量将允许我使用配置late_commit列相同的查询,在做的活(late_commit = FALSE)或更高版本(late_commit =真)时做它。

所以使用查询:

INSERT INTO `tmp`.`new_table` (`a`,`b`,`late_commit`)  
VALUES ('abc','def', IFNULL(@LATECOMMIT, FALSE)); 

我可以用late_commit列设置为false插入值,使得使用IFNULL语句:因为会话变量@latecommit没有定义的代码将配置列假。

在另一方面

,如果我们实际上做离线提交,我们只需要preceed所有插入用:

SET @LATECOMMIT = TRUE; 

,然后用所有必要的插入,这在我的情况下,包括几个继续不同的表,但在所有这些有一个late_commit字段设置为IFNULL(@LATECOMMIT, FALSE)

INSERT INTO `tmp`.`new_table` (`a`,`b`,`latecommit`) 
VALUES ('abc','def', IFNULL(@LATECOMMIT, FALSE)); 

我喜欢这个解决方案,因为该变量只为当前会话,它很容易实现(例如,你。只是预先将您的.sql文件与SET指令挂起并继续执行它)。


TIMEDIFF()或时间戳减法SOLUTION:

当聊天讨论这个,@TehShrike也为我提供了一个SQL唯一的解决办法,我利用的时间之间的差异时,查询是第一次生成的,以及插入的时间。

可以这样做,因为我的表实际上是被插入了clientdate时间戳变量,这是本地UNIX时间戳。

因此,对于这个解决方案所有将需要的是,以确定哪些将被视为late_commit(例如,60秒,1小时后,...),然后使我们的刀片是这样的:

INSERT INTO `tmp`.`new_table` (`a`,`b`,`clientdate`,`latecommit`) 
VALUES ('abc','def', FROM_UNIXTIME(1313489338), 
IF(CURRENT_TIMESTAMP() - clientdate > 3600, TRUE, FALSE)); 

在此插入我们认为,在一个多小时前生成(3600秒)是一个late_commit一个插件。

如果您不使用时间戳,您也可以使用日期时间字段,在这种情况下,您可能会使用DATEDIFF()或TIMEDIFF()函数。

1

我会使默认falselate_commit,并让所有正常的代码忽略它的存在。那么我将不得不通过该注入的late_commit东东“装饰”写入文件去SQL代码,如普通的SQL:

insert into table1 (col1, col2) values (val1, val2); 

但是,当写入文件:

insert into table1 (late_commit, col1, col2) values (true, val1, val2); 

这样只有一段代码需要知道它。 SQL解析来确定在哪里放置额外的位是非常简单的。

+0

当你说装饰器,你的意思是使用SQL字符串,就像搜索和替换功能? –

+0

是的 - 我的意思是一些C代码操纵sql字符串以将额外的位写入文件。 – Bohemian

相关问题