資料庫Select太快...Insert太慢...該怎麼解決?? |
尚未結案
|
Angi
一般會員 發表:16 回覆:56 積分:14 註冊:2005-01-12 發送簡訊給我 |
請問一下喔!
我在做Insert前,會先select流水號,做成一個唯一的編碼
再寫入資料庫
可是,當迴圈在run時,卻會有二筆資料同時取到同一個流水號,因為insert還沒完成,select就又再度執行了,這該怎麼做呢?
舉例:
for i := 1 to (product_x_nums 1) do
begin
//取得今天的日期時間
tmp_nowdate := FormatDateTime('yyyy-mm-dd hh:mm:ss', Now);
//取得資料庫同一時間的下一個編號(編號格式:年月日時分秒加二位流水號)
tmp_expend_detail_code := IncludeFunction.NextCodeExpend(tmp_nowdate, 'member_expend_detail');
//取得流水號
code := Copy(tmp_expend_detail_code,15,2); tmp_str := 'INSERT INTO member_expend_detail (expend_detail_code,date,code) VALUES (''' tmp_expend_detail_code ''',''' tmp_nowdate ''',''' code ''')';
//寫入資料庫的function
Includefunction.sql_add_expend(tmp_str);
//showmessage(tmp_str);
end; 這個程式撰寫上是否有什麼問題,因為常會出現key重覆,只要把showmessage加上,就不會重覆了,請問各位大大是否有好的解決方法呢?
|
pillar62
資深會員 發表:9 回覆:324 積分:271 註冊:2002-04-15 發送簡訊給我 |
|
scotthsiao
高階會員 發表:13 回覆:324 積分:147 註冊:2005-02-01 發送簡訊給我 |
|
Angi
一般會員 發表:16 回覆:56 積分:14 註冊:2005-01-12 發送簡訊給我 |
|
scotthsiao
高階會員 發表:13 回覆:324 積分:147 註冊:2005-02-01 發送簡訊給我 |
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
Hi, 有種做法給你參考, 在 insert 的時候直接 select max 的語法來進行即可, 看你的資料庫種類, 稍微修改一下即可使用, 如, insert into member_expend_detail ('expend_detail_code', 'f1', 'f2') select isnull(max(expend_detail_code), 0) 1, 'my f1 value', 'my f2 value' from member_expend_detail 利用這種語法, 可以在 insert 的同時, 取得最大值加一, 就可以避免掉這個問題.
|
Mickey
版主 發表:77 回覆:1882 積分:1390 註冊:2002-12-11 發送簡訊給我 |
|
scotthsiao
高階會員 發表:13 回覆:324 積分:147 註冊:2005-02-01 發送簡訊給我 |
|
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
|
Angi
一般會員 發表:16 回覆:56 積分:14 註冊:2005-01-12 發送簡訊給我 |
|
lcjan
初階會員 發表:11 回覆:60 積分:29 註冊:2002-03-13 發送簡訊給我 |
引言: 請問scotthsiao 大大 何謂 "使用 store procedure 自動給號"?? 資料庫中的PK是expend_detail_code code就是要用來累加的 現在的問題就是 在第一個select完成,取得code=1,但insert未完成 第二個select就先做了,由於insert未完成,所以code也是等於1 在不改資料庫的情況下,有辦法完成我要的動作嗎??1. 請問您是使用何種資料庫? 2. 取號部分可否使用 Sequence. 3. 整個迴圈是在同一個Transaction嗎? IncludeFunction.NextCodeExpend若是StoreProcedure或Database Fubnction,或由另一Session來讀取,且你在INSERT 第一筆資料後資料庫並未真正commit,那在第二筆取值時若非同一Transaction,極有可能會取到原來的值. 以上是我的推測.. |
Angi
一般會員 發表:16 回覆:56 積分:14 註冊:2005-01-12 發送簡訊給我 |
|
pillar62
資深會員 發表:9 回覆:324 積分:271 註冊:2002-04-15 發送簡訊給我 |
|
lcjan
初階會員 發表:11 回覆:60 積分:29 註冊:2002-03-13 發送簡訊給我 |
引言: 1. 請問您是使用何種資料庫? Mysql 2. 取號部分可否使用 Sequence. 什麼是Sequence?? 3. 整個迴圈是在同一個Transaction嗎? 同一個transaction IncludeFunction.NextCodeExpend 是function "並未真正commit"..我猜也是...不過不知怎麼讓它commit抱歉!我是使用Oracle,MySql並不熟. sequence是oracle中的自動給號物件. Database1.StartTransaction; //啟動交易 Database1.Rollback; //取消交易 Database1.Commit; //確認交易 ADOConnection1.BeginTrans; //啟動交易 ADOConnection1.RollbackTrans; //取消交易 ADOConnection1.CommitTrans; //確認交易 另外,你的迴圈Insert號碼如果是連續的,可否改變一下. 先在迴圈前取得第一號,以變數儲存,迴圈中來作Insert,並累加該變數. 這樣也可避免未commit而產生PK重複問題. |
DragonLucky
一般會員 發表:0 回覆:1 積分:0 註冊:2003-10-15 發送簡訊給我 |
|
Angi
一般會員 發表:16 回覆:56 積分:14 註冊:2005-01-12 發送簡訊給我 |
引言1:
1.請問你是用mySql那一個版本,是否有支援transation??
2.如果你有執行starttransaction那你跟資料庫查詢出來的資料一定都會一樣,因為在還沒有commit之前,資料不會確實存到資料庫!!
3.建議還是用給流水號的方式進行給號的動作!! 1.確定是有支援transaction
2.我就是不知如何確認commit,我在insert後加入一段空迴圈,跑1~180,就可以確認資料已寫入
3.因為其它需求,沒有辦法使用自動給號的pk 引言2:
另外,你的迴圈Insert號碼如果是連續的,可否改變一下.
先在迴圈前取得第一號,以變數儲存,迴圈中來作Insert,並累加該變數.
這樣也可避免未commit而產生PK重複問題. 我也有想過,但是,想請教一下,若不同台機器執行這個檔,而流水號必須全部一起累加,那會不會產生另一個問題? 引言3:
我的做法是, 寫一各取得號碼的Procedure , 然後在這存檔前判斷表格是否為Insert, 如果為Insert, 那麼就調用取的號碼的這个Procedure, 這樣就不會重複, 我寫的程式都是使用這種方式 其實我現在也是類似這個概念,但是就不知道如何"存檔前判斷表格是否為Insert"
|
lcjan
初階會員 發表:11 回覆:60 積分:29 註冊:2002-03-13 發送簡訊給我 |
引言: 引言2: 另外,你的迴圈Insert號碼如果是連續的,可否改變一下. 先在迴圈前取得第一號,以變數儲存,迴圈中來作Insert,並累加該變數. 這樣也可避免未commit而產生PK重複問題. 我也有想過,但是,想請教一下,若不同台機器執行這個檔,而流水號必須全部一起累加,那會不會產生另一個問題?1. 你取號與Insert的Procedure可以用同一個Query作嗎?以確保他們都在同一transation中. 2. 另外提供一個做法, 以Table儲存序號,取號後馬上Update 加 1. |
Angi
一般會員 發表:16 回覆:56 積分:14 註冊:2005-01-12 發送簡訊給我 |
|
lcjan
初階會員 發表:11 回覆:60 積分:29 註冊:2002-03-13 發送簡訊給我 |
引言: Q: 1. 你取號與Insert的Procedure可以用同一個Query作嗎?以確保他們都在同一transation中. 2. 另外提供一個做法, 以Table儲存序號,取號後馬上Update 加 1. A: 1.是同一個Query也是不行,一樣的結果 2.以table儲存序號,馬上update,那和馬上insert不是一樣嗎??難道不會在未update前,就先再度select嗎??這問題可能必須回到"如何確認MySQL已經commit" 在Oracle上我還沒遇到此類問題,且我對MySQL不熟 提供一些參考方向: TDatabase的Translsolation設定值 TDatabase的HandleShared設定值 TQuery的RequestLive設定值 BDE 的 SQLPASSTHUR MODE參數 希望對您有幫助 |
a6475
高階會員 發表:67 回覆:230 積分:154 註冊:2002-09-15 發送簡訊給我 |
我之前也有遇過累似的問題
取得唯一的編號我是用 流水號+時間
由於Delphi的時間是浮點數,只要取小數點之後的數字
大約比豪秒還少。 這樣號碼重覆的幾率會非常的小 ..-----------βλμε------------..
◎Oo月夜 光明 藍更愁oO◎ 藍調月光城v4:http://inping.myweb.hinet.net/ (暫時使用中..) 明日報(藍調.月光):http://mypaper2.ttimes.com.tw/user/a6475
------
月夜 光明 藍更愁 |
Angi
一般會員 發表:16 回覆:56 積分:14 註冊:2005-01-12 發送簡訊給我 |
最後我使用了這個方法 引言 lcjan:
另外,你的迴圈Insert號碼如果是連續的,可否改變一下.
先在迴圈前取得第一號,以變數儲存,迴圈中來作Insert,並累加該變數.
這樣也可避免未commit而產生PK重複問題. 除此之外,就是要注意資料庫的PK
因為原來我以datetime加流水號這個欄位為PK
資料的重覆機率太高
後來,多加了一個卡號的欄位,使得重覆的可能性降低
而且每次一個卡號不可能同時在不同地方使用
自然就可以使用Icjan的方法
所以,其實是我自己在設PK時,沒有考慮清楚
不過,非常謝謝各位大大的寶貴意見,thanks!
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |