2011-10-13 57 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