用于软件间数据交换的mysql自定义查询日志记录
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了用于软件间数据交换的mysql自定义查询日志记录,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5386字,纯文字阅读大概需要8分钟。
内容图文
大约2 – 3年我在SQL服务器中编写了一些触发器(每个表一个),允许我在主软件中记录查询.
ALTER TRIGGER [dbo].[SUIVI_REQUETE_CAT_CATBRUT] ON [dbo].[CAT_CATBRUT] AFTER INSERT, DELETE, UPDATE
AS
DECLARE
@date as nvarchar(10),
@heure as nvarchar(15),
@nomUtilisateur as nvarchar(50),
@poste as nvarchar(50),
@requete as nvarchar(MAX)
BEGIN
set @requete = 'DBCC INPUTBUFFER(' + str(@@SPID) + ')'
CREATE TABLE temporaire (EventType nvarchar(30), Parameters int, EventInfo nvarchar(MAX))
insert into temporaire exec(@requete)
set @requete = (SELECT EventInfo FROM temporaire)
drop table temporaire
set @poste = (SELECT HOST_NAME() AS HostName)
set @nomUtilisateur = (SELECT SUSER_NAME() LoggedInUser)
set @date =(SELECT CONVERT(VARCHAR(10), SYSDATETIME(), 111) AS [YYYY/MM/DD])
set @heure =(select CONVERT(VARCHAR,getdate(),108))
INSERT INTO INF_LOG_REQUETE (REQUETE, POSTE, NOM_UTILISATEUR, [DATE], HEURE) VALUES (LEFT(@requete, 4000), @poste, @nomUtilisateur, @date, @heure)
End
我现在是一个新的网络部门的负责人,我们的目标之一是允许我的网络软件与我们的主要软件共享数据.我想在表格(客户,车辆,员工,日历等)中保存一些关键行,我们希望在两个软件之间共享.
关于我的问题我有三个问题:
>我想仅针对特定数据库用户记录查询(我们不希望陷入无限循环的来回发送相同的修改).在SQL服务器中,我用它来检测用户:
set @nomUtilisateur =(SELECT SUSER_NAME()LoggedInUser)
是否有可能检测到在MySQL中执行查询的用户?
>在SQL Server中,我能够在插入,更新和删除操作上使用相同的触发器.
是否可以在MySQL中执行相同的操作或者是否必须从每个表中编写三个不同的触发器?
>如果相同的触发器可用于多个操作(插入,更新,删除),是否可以检测启动触发器的操作(插入,更新,删除)?
附加说明:我想在表中仅记录特定字段(包含要共享的密钥数据).我真的想为每个表编写一个触发器,这样PHP函数就可以自动用数据解析字段并构建一个XML文件.例如,我想在我的日志表中包含一个字段,其中包含:
{table}:[vehicle], {action}:[insert], {field}:[make], {value}:[acura], {field}:[model], {value}:[S7], ...
并生成如下XML:
<LIST>
<QUERY>
<TABLE>vehicle</TABLE>
<ACTION>insert<ACTION>
<FIELD>make</FIELD>
<VALUE>acura</VALUE>
<FIELD>model</FIELD>
<VALUE>S7</VALUE>
...
</QUERY>
<QUERY>
...
</QUERY>
<QUERY>
...
</QUERY>
</LIST>
谢谢
解决方法:
好的,经过一些研究,这是我找到的答案.
Q1:是否有可能检测到在MySQL中执行查询的用户?
可以使用以下方法检测哪个用户:select user();
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_user
注意:在触发器和事件中,current_user()返回定义对象的用户(在SP和视图中,除非使用SQL SECURITY INVOKER定义).您确实需要使用user()函数在这些上下文中返回调用者.
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_current-user
Q2:是否可以在同一个触发器上触发多个动作(INSERT,UPDATE,DELETE)?
最不幸的是,在当前时间(2016/02/01),不可能在MySQL中同时触发两个动作.我们所能做的最好的事情是在存储过程中重新组合通用编码.
以下过程是解决此问题的一种可能方法.它期望输入:
> callingTable:我们要为其记录查询的表的名称(必须在白名单中).
>动作:’删除’,’插入’或’更新’.
> fieldsValues:包含XML中有效字段/值对的字符串.例如:< field> ID< / field>< value> 1616< / value>
CREATE PROCEDURE `dataLinkRecorder` (
IN callingTable VARCHAR (25),
IN action ENUM('DELETE', 'INSERT', 'UPDATE'),
IN fieldsValues TEXT
)
BEGIN
DECLARE callingUser VARCHAR(25) DEFAULT '';
DECLARE fieldCount SMALLINT UNSIGNED DEFAULT 0;
DECLARE fieldCCount SMALLINT UNSIGNED DEFAULT 0;
DECLARE valueCount SMALLINT UNSIGNED DEFAULT 0;
DECLARE valueCCount SMALLINT UNSIGNED DEFAULT 0;
IF (TRIM(fieldsValues) <> '') THEN
/* the calling table must be one in the white list */
SELECT CASE
WHEN UPPER(callingTable) IN (
'CATEGORY',
'CUSTOMER',
'MAKE',
'MODEL',
'PRODUCT',
'VEHICLE'
)
THEN TRIM(UPPER(callingTable))
ELSE ''
END AS myTable
INTO callingTable;
SELECT TRIM(
UPPER(
IFNULL(USER(), 'CLIENT')
)
) AS myUser
INTO callingUser;
/* do not record modifications from tier software */
IF (callingTable <> '' AND INSTR(callingUser, 'CLIENT') < 1) THEN
SELECT IFNULL(
((CHAR_LENGTH(fieldsValues) - CHAR_LENGTH(REPLACE(fieldsValues, '<field>', ''))) / 7)
, 0) AS fCount,
IFNULL(
((CHAR_LENGTH(fieldsValues) - CHAR_LENGTH(REPLACE(fieldsValues, '</field>', ''))) / 8)
, 0) AS fCCount,
IFNULL(
((CHAR_LENGTH(fieldsValues) - CHAR_LENGTH(REPLACE(fieldsValues, '<value>', ''))) / 7)
, 0) AS vCount,
IFNULL(
((CHAR_LENGTH(fieldsValues) - CHAR_LENGTH(REPLACE(fieldsValues, '</value>', ''))) / 8)
, 0) AS vCCount
INTO fieldCount, fieldCCount, valueCount, valueCCount;
/* validate the field/value XML pair */
IF (fieldCount > 0 AND
valueCount > 0 AND
fieldCount = fieldCCount AND
valueCount = valueCCount AND
fieldCount = valueCCount
) THEN
INSERT INTO `pc_datalink`
(`table_name`, `query_xml`)
VALUES(
callingTable,
CONCAT(
'<query>',
'<table>', callingTable, '</table>',
'<action>', action, '</action>',
fieldsValues,
'</query>'
)
);
END IF;
END IF;
END IF;
END //
将在下表中插入值:
CREATE TABLE `pc_datalink` (
`id` int(10) UNSIGNED NOT NULL,
`table_name` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
`query_xml` text COLLATE utf8_unicode_ci NOT NULL,
`date_added` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `AK_DATE_ADDED` (`date_added`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
举个例子,像这样一个非常简单的触发器:
CREATE TRIGGER `dataLinkDeleteVehicle` AFTER DELETE ON `pc_vehicle`
FOR EACH ROW
BEGIN
IF (OLD.original_id <> '') THEN
CALL dataLinkRecorder(
'VEHICLE',
'DELETE',
CONCAT(
'<field>ID</field><value>',
OLD.original_id,
'</value>'
)
);
END IF;
END //
会像这样在表格中生成一条线:
如果您仍有疑问,请随时询问详细信息,
大家都很成功
内容总结
以上是互联网集市为您收集整理的用于软件间数据交换的mysql自定义查询日志记录全部内容,希望文章能够帮你解决用于软件间数据交换的mysql自定义查询日志记录所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。