  | 
				VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.   
				 | 
			 
		 
		 
	
		| 上一篇主題 :: 下一篇主題   | 
	 
	
	
		| 發表人 | 
		內容 | 
	 
	
		jasonyummy
 
 
  註冊時間: 2004-05-06 文章: 15
 
  第 1 樓
  | 
		
			
				 發表於: 星期四 六月 10, 2004 4:12 pm    文章主題: oldval() 與 curval() 的問題 | 
				     | 
			 
			
				
  | 
			 
			
				如題:
 
我在開發遠端資料庫, 後端用的是 SQL2000 前端用的是 vfP 6.0 sp5
 
我在前端設立一條通道 connect1 ,非同步執行與批次處理都有打勾
 
*---
 
然後利用此通道建立了一個 view 名為 outp_v (後端sql為outp) [銷貨主擋]
 
與 opitem_v (後端sql為opitem)  [銷貨明細擋]
 
*---
 
此 outp 設了索引 為 tradeno(單號)
 
此 opitem 設了兩個共同索引 為 tradeno(單號) line_no(項次)
 
*------
 
然後設計了一個 form
 
把 outp_v 與 opitem_v 都拉了進來
 
outp_v buffer 設 3
 
opitem_v buffer 設 5
 
*---
 
最近有一問題困擾了我很久, 查了vfp的說明,明明寫的很清楚.
 
可以用 oldval() , curval() 來判斷是否有人先一步更改資料,
 
 
但經過我的測試結果, 很奇怪
 
 
例如:
 
有一張銷貨單 單號 A001 貨號 CCC 單價 100 項次 1
 
欄位名           tradeno,goodno,saleprice,line_no
 
 
有二人 A , B
 
 
1.
 
A先打開 form 叫出單號 A001的銷貨單
 
把 opitem_v 內的 銷貨單價 saleprice 100 修正成 50 
 
尚未存檔
 
oldval('saleprice')=100
 
curval('saleprice')=100
 
saleprice=50
 
 
2.
 
B此時進來,也打開 A001
 
尚未修改時,用 oldval(),curval()看時
 
oldval('saleprice')=100
 
curval('saleprice')=100
 
saleprice=100
 
現在B修正 saleprice為 10
 
 
此時再看一次
 
oldval('saleprice')=100
 
curval('saleprice')=100
 
saleprice=10
 
好,把它存檔 用 tableupdate(.t.,.f.)結果回覆成功=.T.
 
 
此時再看一次, 結果都變成了 10
 
oldval('saleprice')=10
 
curval('saleprice')=10
 
saleprice=10
 
 
3.
 
這時回到 A
 
先看一下, 還是沒有變
 
oldval('saleprice')=100
 
curval('saleprice')=100
 
saleprice=50
 
 
到這裡時我就感到很奇怪, 不是B已經修改成 10 ,為何還是不變呢?
 
不是可以用oldval(),curval()來判斷嗎?
 
 
4.
 
然後我不管的繼續
 
把A也一樣的存檔, 用 tableupdate(.T.,.F.) 結果回覆不成功=.F.
 
錯誤訊息=1585 (記錄已被其他使用者修改)
 
 
真奇怪, 它知道有被更改,但是為何oldval(),curval() 的值不變呢?
 
 
此時,我只好用 tableupdate(.T.,.T.)來強制存檔,結果回覆成功=.T.
 
 
這時我再看一次, 都變成 50
 
oldval('saleprice')=50
 
curval('saleprice')=50
 
saleprice=50
 
 
為了這個問題,我花費了很長時間測試,結果仍然一樣
 
各位先進們之前對於oldval(),curval()有三篇文章,我看了經過實際測試還是一樣
 
不知道我哪裡弄錯了,
 
所以就打擾各位,請各位前輩指導我,麻煩各位了
 
 
在此先向你們說聲 謝謝 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		catjoke
 
 
  註冊時間: 2003-06-16 文章: 175 來自: 香港
  第 2 樓
  | 
		
			
				 發表於: 星期四 六月 10, 2004 5:53 pm    文章主題:  | 
				     | 
			 
			
				
  | 
			 
			
				OldVal() & EVAL()
 
 
記著不要做 TABLEUPDATE()
 
以及不要用 BUFFER 3, 因為 recno() 一走就存檔了..   _________________ 喵喎~ 貓當然是 "茅" 的嘛! ^0^; | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		syntech
 
 
  註冊時間: 2003-05-16 文章: 4252 來自: Taipei,Taiwan
  第 3 樓
  | 
		
			
				 發表於: 星期四 六月 10, 2004 5:56 pm    文章主題:  | 
				     | 
			 
			
				
  | 
			 
			
				你的實驗是對的,
 
但是.......
 
oldval()及curval()是指目前client 端的old value 及 current value,
 
並非 SQL server 上的欄位值
 
 
等到存檔時
 
vfp 會組合如下方的 sql command 到後端執行:
 
 
UPDATE 銷貨單 SET saleprice = curval() where trano='XXXX' and saleprice=oldval()
 
 
SQL SERVER這時才會檢查
 
 
如果發現找不到可更新記錄,就表示"記錄已被其他使用者修改" _________________ 如果公司有下列困擾:
 
1. 找不到便宜,快速,簡易的 生產排程軟體
 
2. 不知道如何快速排定 採購計劃
 
3. 成本抓不準,自己算比軟體算有用
 
4. 想學習系統規劃,想找系統架構的顧問
 
 
請聯絡我們,也許我們幫得上忙 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		syntech
 
 
  註冊時間: 2003-05-16 文章: 4252 來自: Taipei,Taiwan
  第 4 樓
  | 
		
			
				 發表於: 星期四 六月 10, 2004 6:18 pm    文章主題:  | 
				     | 
			 
			
				
  | 
			 
			
				curval() 的說明提到 value 和 curval() 不一致的原因
 
 
Note   If you are working with a view in a multiuser environment, the values returned by CURVAL( ) might not be up to date unless you call the REFRESH( ) function first. Data returned by a view is buffered, and the CURVAL( ) function reads values from the buffer. However, if other users have changed data in the underlying tables for the view, the buffered data is not updated until the REFRESH( ) function is called _________________ 如果公司有下列困擾:
 
1. 找不到便宜,快速,簡易的 生產排程軟體
 
2. 不知道如何快速排定 採購計劃
 
3. 成本抓不準,自己算比軟體算有用
 
4. 想學習系統規劃,想找系統架構的顧問
 
 
請聯絡我們,也許我們幫得上忙 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		jasonyummy
 
 
  註冊時間: 2004-05-06 文章: 15
 
  第 5 樓
  | 
		
			
				 發表於: 星期五 六月 11, 2004 10:14 am    文章主題:  | 
				     | 
			 
			
				
  | 
			 
			
				照你的意思是說
 
 
目前要判斷是否有人先一步更改 SQL 值時,
 
只能在發生存檔失敗 ERROR=1585 ,然後自己到SQL取值來判斷是哪個欄位
 
已經被更改,及更改成何值.
 
 
然道沒有比較好的方法嗎?
 
 
謝謝指教 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		goto-dream
 
 
  註冊時間: 2004-05-11 文章: 909
 
  第 6 樓
  | 
		 | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		jasonyummy
 
 
  註冊時間: 2004-05-06 文章: 15
 
  第 7 樓
  | 
		
			
				 發表於: 星期五 六月 11, 2004 3:02 pm    文章主題:  | 
				     | 
			 
			
				
  | 
			 
			
				謝謝
 
 
我可能要墊高枕頭好好的想一想 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		jasonyummy
 
 
  註冊時間: 2004-05-06 文章: 15
 
  第 8 樓
  | 
		
			
				 發表於: 星期一 六月 14, 2004 2:54 pm    文章主題:  | 
				     | 
			 
			
				
  | 
			 
			
				哈!
 
我用一個方法, 不用自己寫函數也能得到我想要的, 雖然不滿意,但是還能接受
 
 
做法:
 
不要用全部更新的方法,用一筆一筆存的方式---
 
[ 用 tableupdate(.F.,.F.) ,不要用 tableupdate(.T.,.F.) ]
 
 
然後若有發生 1585 錯誤時,提出訊息告訴使用者[資料有更動,是否覆蓋,不更動,或取消存檔](若想要完美些,可以在這個時候讀取SQL的資料判斷哪些值有變動)
 
 
1.選擇覆蓋的話,則在最後面,再作一次 Tableupdate(.T,.T.)即可
 
 
2.若是選擇不更動的話,則用 Tablerevert(.F.)回覆一筆資料,仍然在最後面作一次Tableupdate(.T,.T.)
 
 
3.選擇不存檔的話,則返回,該復原緩衝的復原,若要回覆未修正時的資料用Tablerevert(.T.), 反則不要作
 
 
用GETNEXTMODIFIED(0)來判斷更動資料, 會有不正確的問題(若有覆蓋與不更動同時進行時)
 
 
所以我才用一筆一筆的存來彌補這個問題.
 
 
以上是我參考VFP說明檔內的 第十七章:共同存取之程式設計
 
加以測試, 然後取沒有問題的方法得到的, 你們可以去看看.
 
 
最後結語:
 
當然有許多細節要注意, 不過怕在關老爺面前耍大刀,貽笑大方,
 
 
一方面又想要讓這篇有頭有尾, 比較像樣些.所以就簡簡單單作個結尾,
 
 
謝謝大家 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		syntech
 
 
  註冊時間: 2003-05-16 文章: 4252 來自: Taipei,Taiwan
  第 9 樓
  | 
		
			
				 發表於: 星期一 六月 14, 2004 3:18 pm    文章主題:  | 
				     | 
			 
			
				
  | 
			 
			
				猛一看,怎麼覺得是手冊上的作法,
 
原來真的是....
 
 
前面有關CURVAL()的說法不太對,
 
有時間再改一下.
 
CURVAL()手冊是說"現在在TABLE上的值",
 
可是SPT時,能不能拿不到"現在在TABLE上的值",
 
無論如何 ,不是
 
UPDATE 銷貨單 SET saleprice = curval() where trano='XXXX' and saleprice=oldval() 
 
 
而是
 
UPDATE 銷貨單 SET saleprice = 'field value' where trano='XXXX' and saleprice=oldval() 
 
 
遇到更新衝突時,才利用 CURVAL()判斷.
 
 
遇到更新衝突的作法,
 
每家公司的策略都不同,
 
我看過有家軟體公司的系統是不管有沒有衝突,
 
都由"後來存檔"的記錄為記錄,
 
即使這些記錄是過時的.
 
 
逐筆處理也是一種方法.
 
可是實務上卻應該以'整張單據'的處理來看,
 
這一整張單據只要有一筆失敗就應該是為整張都失敗,
 
才不會發生總計項目(也許放在表頭)與表身明細不一致的情況.
 
 
我在設定更新衝突的做法時,
 
是使用 更新衝突->提出警告並放棄->重新取得資料->編輯->再次更新
 
有的時候,使用者會面臨非得放棄一堆剛剛才打資料不可,
 
針對這點,我控制一次處理一張單據為原則,
 
編輯只能編輯一張單據,
 
所以存檔也是一張,放棄也是一張,
 
代價不會太高.
 
 
如果一張單據也會更新衝突,表示該公司事權不一致,也說的過去,
 
畢竟同一張單據不應該於同一時間由不同的人編輯
 
 
如何處理更新衝突是一門專業的學問,
 
應該花時間好好研究. _________________ 如果公司有下列困擾:
 
1. 找不到便宜,快速,簡易的 生產排程軟體
 
2. 不知道如何快速排定 採購計劃
 
3. 成本抓不準,自己算比軟體算有用
 
4. 想學習系統規劃,想找系統架構的顧問
 
 
請聯絡我們,也許我們幫得上忙 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
  	 
	    
  	   | 
 	
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
  | 
   
  
		 |