如何在Ms sql server 中實現Oracle 中的 For Update Nowait 功能? |
答題得分者是:Mickey
|
agilehawk
一般會員 發表:3 回覆:10 積分:7 註冊:2008-09-05 發送簡訊給我 |
如何在Ms sql server 中實現Oracle 中的 For Update Nowait 功能?
我想實現在 MS Sql Server 中實現類是 Oracle中的如下語句, select * from patient where patientid =111 for Update nowait , 請問如何實現? This is more of a database question. I have a Windows Service and a Client application that need to update an Employee table. Both of them are calling a Web Service which calls a stored procedure. Suppose each of them wants to update the same row (employee). How in MS Sql Server do I do a "lock", so that only one of them is updating a specific row at a time, to prevent data collisions which result in corrupted data? I know in Oracle you can do a "SELECT FOR UPDATE NOWAIT". Any thoughts or ideas are greatly appreciated. 編輯記錄
agilehawk 重新編輯於 2008-09-06 06:56:30, 註解 無‧
|
Mickey
版主 發表:77 回覆:1882 積分:1390 註冊:2002-12-11 發送簡訊給我 |
|
agilehawk
一般會員 發表:3 回覆:10 積分:7 註冊:2008-09-05 發送簡訊給我 |
|
OsX
版主 發表:6 回覆:151 積分:111 註冊:2003-05-03 發送簡訊給我 |
|
agilehawk
一般會員 發表:3 回覆:10 積分:7 註冊:2008-09-05 發送簡訊給我 |
|
Mickey
版主 發表:77 回覆:1882 積分:1390 註冊:2002-12-11 發送簡訊給我 |
MSSQL ISQL 與 ORACLE PLSQL...還是有差別
for update nowait...與 holdlock...確實也不太一樣. 以前我是用 SQL 檢查該 Table 是否有被其他程序 Lock...並且配合 Transaction 的使用 參考看看囉 function LockBDEDataSet(DS : TQuery):boolean; var fsql,DBType,fTableName,fHostName: string; t:hDBICur; r:DBIResult; OldInTran : Boolean; begin if not DS.Active then raise Exception.CreateFmt('DataSet %s is not actived.',[DS.Name]); DBType := DS.Database.Session.GetAliasDriverName(DS.Database.AliasName); fTableName := GetTableNamefromSQL(DS.SQL.Text); if CompareText(DBType,'Oracle')=0 then fsql := DS.SQL.Text ' for update nowait' else if CompareText(DBType,'MSSQL')=0 then fsql := StringReplace(DS.SQL.Text,fTableName,fTableName ' with (HOLDLOCK)',[rfReplaceAll, rfIgnoreCase]) else if CompareText(DBType,'SYBASE')=0 then fsql := StringReplace(DS.SQL.Text,fTableName,fTableName ' HOLDLOCK',[rfReplaceAll, rfIgnoreCase]) else raise Exception.CreateFmt('Unsupported DBMS %s.',[DBType]); OldInTran := DS.Database.InTransaction; if not DS.Database.InTransaction then DS.Database.StartTransaction; r := DbiQExecDirect(DS.Database.Handle,qrylangSQL,PChar(fsql),@t); if CompareText(DBType,'Oracle')=0 then fsql := 'select S.TERMINAL from SYS.GV_$LOCKED_OBJECT L,ALL_OBJECTS O,SYS.GV_$SESSION S ' 'where L.SESSION_ID=S.SID and S.AUDSID<>USERENV('#39'SESSIONID'#39') and ' 'L.ORACLE_USERNAME=USER and O.OWNER=USER and O.OBJECT_ID=L.OBJECT_ID and ' 'S.SID=L.SESSION_ID and O.OBJECT_NAME='#39 fTableName #39 else if (CompareText(DBType,'MSSQL')=0)or(CompareText(DBType,'SYBASE')=0) then fsql := 'select p.hostname from master.dbo.syslocks l,master.dbo.sysprocesses p ' 'where l.spid=p.spid and l.spid<>@@spid and object_name(l.id)='#39 fTableName #39 else raise Exception.CreateFmt('Unsupported DBMS %s.',[DBType]); with TQuery.Create(nil) do begin try DataBaseName := DS.DatabaseName; SQL.Text := fsql; Open; if not (Eof and Bof) then begin if Trim(Fields[0].asstring)='' then fHostName:='Unknown' else fHostName := Fields[0].asstring; if (Integer(t)=0)or(r<>DBIERR_NONE) then begin if not OldInTran then DS.Database.Rollback; raise Exception.CreateFmt('鎖定資料失敗. 資料檔 %s 已被 %s 鎖定中.',[fTableName,fHostName]); end; Application.MessageBox(PChar(Format('資料檔 %s 可能已被 %s 鎖定.',[fTableName,fHostName])),'警告'); end; finally Free; end; end; Result := True; end; |
OsX
版主 發表:6 回覆:151 積分:111 註冊:2003-05-03 發送簡訊給我 |
|
agilehawk
一般會員 發表:3 回覆:10 積分:7 註冊:2008-09-05 發送簡訊給我 |
===================引 用 OsX 文 章=================== > select * from XXX with ( XLOCK, NOWAIT) where 1 = 1 > 此種方法已經試用過,不能得到想要的結果,還是會同時允許修改 此種方法已經用過, 不可以同時修改, 沒有問題 Delphi7 ADO MSSQL 2000 XP Client 今日再次測試此種方法,確實能同時修改,只是只要有一個提交修改后,其他終端再提交保存修改時即會得到報錯信息“無法為更新定位行。一些值肯能已在最后一次讀取后已經更改。”! 其實在任何數據庫中,用不用 with (xlock ,nowait) ,都能起到這樣的結果,所以以上語句在這種情況下,等同于 select * from XXX where 1=1 而我要的不是這個結果,我不能在用戶用去幾分鐘的時間編輯數據后,才給她提示不能保存,這樣要是我,我也會變成神經質的啦! |
OsX
版主 發表:6 回覆:151 積分:111 註冊:2003-05-03 發送簡訊給我 |
|
agilehawk
一般會員 發表:3 回覆:10 積分:7 註冊:2008-09-05 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |