2011-10-13 163 views
3

我试图找到如何将查询中的变量发送到触发器,但它会影响第二个表。我用它来创建一个日志表,其中任何被更新或插入被记录在日志表例如PHP的MySQL触发器 - 如何传递变量来触发?

//Inserts into the table the username and password 
$sql = "INSERT INTO table VALUES ($_POST['username'], $_SESSION['password']); 

触发DDL语句

DELIMITER $$ 

//Creates trigger to insert into table1 (logs) the userid and patientid (which has to come from php) 
USE `baemer_emr`$$ 

CREATE 
DEFINER=`baemer_emr`@`localhost` 
TRIGGER `table1`.`after_insert` 
AFTER INSERT ON `baemer_emr`.`table1` 
FOR EACH ROW 
BEGIN 
    INSERT INTO table2 VALUES (NEW.idn, $_POST[userid], $_SESSION[patientid]); 
END$$ 

这可能吗?

回答

0

我不认为这是。

您可以将useridpatientid列添加到VALUES表中,在原始插入期间填充它们,然后在插入日志表时引用触发器中的那些列。

alter table `baemer_emr`.`table1` add userId varchar(100); 

alter table `baemer_emr`.`table1` add patientId int unsigned; 

,然后触发:

DELIMITER $$ 

//Creates trigger to insert into table1 (logs) 
USE `baemer_emr`$$ 

CREATE 
DEFINER=`baemer_emr`@`localhost` 
TRIGGER `table1`.`after_insert` 
AFTER INSERT ON `baemer_emr`.`table1` 
FOR EACH ROW 
BEGIN 
    INSERT INTO table2 VALUES (NEW.idn, NEW.userId, NEW.patientId); 
END$$ 

DELIMITER ; 
+0

将冗余数据添加到表不看像一个有用的解决方案 – Johan

+0

够公平的。我不知道黑洞的存在。我现在做的。有用的提示。 –

12

修复了SQL注入

$username = mysql_real_escape_string($_POST['username']); 
$password = mysql_real_escape_string($_POST['password']); 
$sql = "INSERT INTO table1 VALUES ('username','password'); 
// You must quote your $vars  ^ ^^  ^like this 
// or syntax errors will occur and the escaping will not work!. 

注意,在数据库中存储未加密的密码是一个大忌。
请参阅以下有关如何解决该问题。

触发器不允许参数
您只能访问刚插入到表中的值。
插入触发器有一个虚拟表new为此。
Delete triger有一个虚拟表old来查看要删除的值。
更新触发器同时具有oldnew

除此之外,您无法访问任何外部数据。

DELIMITER $$  

//Creates trigger to insert into table1 (logs) the userid and patientid (which has to come from php)  

CREATE  
TRIGGER ai_table1_each AFTER INSERT ON `baemer_emr`.`table1`  
FOR EACH ROW  
BEGIN  
    INSERT INTO table2 VALUES (NEW.idn, NEW.username, NEW.patientid);  
END$$  

解决方案
新建黑洞表。
黑洞表不存储任何东西,他们存在的唯一原因是为了复制的目的,所以你可以附加触发器给他们。

CREATE TABLE bh_newusers (
    username varchar(255) not null, 
    password varchar(255) not null, 
    idn integer not null, 
    patient_id integer not null, 
    user_id integer not null) ENGINE = BLACKHOLE; 

接下来将数据插入黑洞表并使用触发器进行处理。

CREATE  
TRIGGER ai_bh_newuser_each AFTER INSERT ON `baemer_emr`.bh_newuser 
FOR EACH ROW  
BEGIN  
    DECLARE newsalt INTEGER; 
    SET newsalt = FLOOR(RAND()*999999); 
    INSERT INTO users (username, salt, passhash) 
    VALUES (NEW.username, newsalt, SHA2(CONCAT(newsalt, password), 512)); 
    INSERT INTO table2 VALUES (NEW.idn, NEW.username, NEW.patient_id); 
END$$  

注意事项触发
你不应该在明文密码存储在数据库中。
使用最安全的散列函数(目前SHA2的密钥长度为512),始终将它们存储为盐味散列,如触发器所示。
您可以测试,看看是否有人做了正确的密码:

SELECT * FROM user 
WHERE username = '$username' AND passhash = SHA2(CONCAT(salt,'$password'),512) 

链接
http://dev.mysql.com/doc/refman/5.0/en/blackhole-storage-engine.html
http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
Storing hashed passwords in MySQL
How does the SQL injection from the "Bobby Tables" XKCD comic work?

+0

我使用PHP函数MD5,它够好吗? 伟大的答案顺便说一句,所以换句话说,我需要做一个插入黑洞表,并从那里做必要的插入。 – Skynight

+1

@Skynight,我建议不要使用MD5,它已经被破解了一段时间,并且SHA2是安全的,但是当涉及到散列缓慢时,这是一件**好事。 – Johan

+1

@Skynight,插入黑洞会将所有数据直接发送到触发器,触发器内部可以重新分配数据。这还带来了额外的好处,即所有的插入都发生在单个事务中,因为触发器中的所有代码都被包装在一个事务中。 – Johan