2011-05-12 69 views
0

我正在使用mysql/php。難以插入

我的表看起來像

id (int autoincrement) 
voucher(varchar 25) 

我生成優惠券代碼,其中該代碼是:

  • 1張的隨機數(例如64)
  • 1個固定數量(例如352)
  • id字段的值(1,2,3,4,5 ...)
  • 1 checkdigit(luhn算法)。

在做這個與php的顯而易見的問題是,我必須做一個選擇,獲得下一個自動增量值,計算代碼,插入,到哪個時間可以插入另一行。

我想要做的就是代替,

insert into vouchers (voucher) value('64352'),讓它產生了我的其餘部分。

我該怎麼做?功能/觸發?

回答

1

如果你使用的是InnoDB,一個簡單的解決方法就是使用你現有的代碼並將其包裝在MySQL事務中。即在僞代碼:

mysql_query("START TRANSACTION"); 

# get next autoincrement value into: $next 

# do your INSERT query 

# get the actual last inserted ID into: $actual 

if ($next === $actual) { 
    mysql_query("COMMIT"); 
} else { 
    mysql_query("ROLLBACK"); 
    # and raise an Exception or return an error 
} 

編輯/添加:

既然你提到的觸發器,我看着成,並認爲這是可行的。幾個問題。

  1. 從觸發器訪問「下一個自動增量ID」...我不知道這樣做的「好」方法。在INSERT查詢中,您只能訪問NEW而不訪問OLD(現有行)值(請參閱Trigger syntax)。我在這個例子中所做的只是在服務器上維護一個單獨的計數器@vcount。要將此值初始化爲當前ID的任何值,只需執行「SET @vcount = 42;」

  2. Luhn算法。您必須將其作爲SQL函數來實現。 Here's SQL中的一個Luhn驗證器,您可以從中剔除。或者,您可以使用本機MySQL函數(如MD5)進行散列/校驗和(如果需要短代碼代碼,則只使用前X個字符)。在任何情況下,你需要做一個哈希函數...我只會使用下面的「Luhn」。

反正這裏的觸發會是什麼樣子:

delimiter // 
CREATE TRIGGER make_voucher_code BEFORE INSERT ON vouchers 
FOR EACH ROW 
BEGIN 
    SET @vcount = @vcount + 1; 
    SET NEW.voucher = CONCAT(
     NEW.voucher, 
     CAST(@vcount AS CHAR), 
     Luhn(CONCAT(NEW.voucher, CAST(@vcount AS CHAR)))); 
END; 
// 
delimeter ; 

然後,在你的插入,你會在查詢放只是「64352」,因爲你已經建議。觸發器會附加其餘的。個人而言,除非你或其他人可以更好地解決autoincrement/@ vcount問題,否則我仍然更願意進行MySQL事務處理,這將比保持所有原子操作並將所有應用程序代碼保存在PHP中做得更好。

+0

概率應該提到我使用的代碼點火器... – Hailwood 2011-05-12 01:00:53

+0

我一直在尋找MySQL的觸發器,我相信這是可行的。我會用一些半個示例代碼更新我的答案。或者,您仍然可以通過代碼點火器來完成交易。將應用程序代碼嵌入到觸發器/存儲過程中有其優點和缺點。 – joelhardi 2011-05-12 01:17:20

+0

OK,我的觸發結束了更多比我預想的完全成熟。添加一個Luhn函數,它應該可以工作。在我的例子盧恩()將返回校驗值作爲一個字符串,所以如果你有這回你只需要包裝科協返回值(AS CHAR)將int。祝你好運! – joelhardi 2011-05-12 01:53:10

0

或者做值爲0的插入,然後獲取插入ID,計算值並更新記錄。