VFP 愛用者社區 首頁 VFP 愛用者社區
本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入

oldval() 與 curval() 的問題

 
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區
上一篇主題 :: 下一篇主題  
發表人 內容
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() 一走就存檔了.. Sad

_________________
喵喎~ 貓當然是 "茅" 的嘛! ^0^;
回頂端
檢視會員個人資料 發送私人訊息
syntech



註冊時間: 2003-05-16
文章: 4212
來自: 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. 想學習系統規劃,想找系統架構的顧問

請聯絡我們,也許我們幫得上忙
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 AIM Address
syntech



註冊時間: 2003-05-16
文章: 4212
來自: 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. 想學習系統規劃,想找系統架構的顧問

請聯絡我們,也許我們幫得上忙
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 AIM Address
jasonyummy



註冊時間: 2004-05-06
文章: 15


第 5 樓

發表發表於: 星期五 六月 11, 2004 10:14 am    文章主題: 引言回覆

照你的意思是說

目前要判斷是否有人先一步更改 SQL 值時,
只能在發生存檔失敗 ERROR=1585 ,然後自己到SQL取值來判斷是哪個欄位
已經被更改,及更改成何值.

然道沒有比較好的方法嗎?

謝謝指教
回頂端
檢視會員個人資料 發送私人訊息
goto-dream



註冊時間: 2004-05-11
文章: 909


第 6 樓

發表發表於: 星期五 六月 11, 2004 2:20 pm    文章主題: 引言回覆

寫各oldval()及curval()取代他
去判斷已經被更改,及更改成何值

_________________
福隆昌淨水有限公司--淨水器的專家,淨水器,飲水機,濾心!!

想了解更多,您可上幸福雞湯組.找尋!!丁澐瑄.老師.

          愛作夢
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件
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
文章: 4212
來自: 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. 想學習系統規劃,想找系統架構的顧問

請聯絡我們,也許我們幫得上忙
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 AIM Address
從之前的文章開始顯示:   
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區 所有的時間均為 台北時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
無法 在這個版面附加檔案
無法 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作