sql語法一句 |
尚未結案
|
jacosun
一般會員 發表:42 回覆:64 積分:21 註冊:2003-04-18 發送簡訊給我 |
程式碼如下
try
DataBase1.StartTransaction;
Table1.first;
while not Table1.eof do
begin
Query1.close;
Query1.sql.add('select * from stock ');
Query1.sql.add('where thing_no="' Table1.fields[0].asstring '"');
Query1.open
//若有相同的貨號即累加,沒有則新增。
if Query1.RecordCount=0 then
Query2.close;
Query2.sql.add('insert stock(thing_no,much,money)');
Query2.sql.add('value("' Table1.fields[0].asstring '","' Table1.fields[1].asstring''","' Table1.fields[2].asstring '")');
Query2.Execsql;
end
else begin
Query2.close;
Query2.sql.add('update stock set much=much "' Table1.fields[1].asstring '",money=money "' Table1.fields[2].asstring '"');
Query2.sql.add('where Thing_no="' Table1.fields[0].asstring '"');
Query2.Execsql;
end;
Table1.next;
end;
DataBase1.commit;
except
DataBase1.Rollback;
showmessage('資料有誤');
end;
Table1是一個暫時的表格(讓使用者輸入資料後然後按存檔才會寫入stock資料表裡),請問各位大大,在判斷是否有重覆貨號的程式是否有別的寫法。
另外即這樣的寫法會造成無法執行完成。可否請大大們提供一下建議
謝謝 發表人 - jacosun 於 2004/09/20 12:47:02
|
pgdennis
資深會員 發表:41 回覆:526 積分:443 註冊:2002-05-23 發送簡訊給我 |
|
jacosun
一般會員 發表:42 回覆:64 積分:21 註冊:2003-04-18 發送簡訊給我 |
引言: Query1.sql.add('where thing_no=Table1.fields[0].asstring'); 改成Query1.sql.add('where thing_no=' #39 Table1.fields[0].asstring #39); ''<---裡面是送出的SQL,你把Table1.fields[0].asstring包在裡面 資料庫怎會認得這是什麼東東 星期一,星期二...星期日..星期一..無窮迴圈@@ >>< face="Verdana, Arial, Helvetica"> 拍謝拍謝,早上因為剛睡醒頭昏昏的 沒寫完整。請大大再幫我看一下。 |
yenhorng
中階會員 發表:12 回覆:82 積分:94 註冊:2002-06-18 發送簡訊給我 |
為避免資料重複建立(索引唯一),我的作法如下,請參考:
使用DBF,DELPHI7........
procedure TForm_Set_Login.Query_Down_StaffBeforePost(DataSet: TDataSet);
begin
if Trim(DBEdit1.EditText) = '' then
begin
ShowMessage('員工姓名不得空白!');
Abort;
DBEdit1.SetFocus;
end;
//
with Query_Temp do
begin
Close;
SQL.Clear;
SQL.Add('SELECT * FROM STAF_LOGI');
SQL.Add('WHERE S_NAME = "' Trim(DBEdit1.EditText) '"');
Open;
end;
if ((Query_Down_Staff.State = dsInsert) and (Query_Temp.RecordCount > 0)) or
((Query_Down_Staff.State = dsEdit) and (Query_Temp.RecordCount > 1) and (Query_Down_Staff.FieldByName('S_NAME').NewValue = Query_Down_Staff.FieldByName('S_NAME').OldValue)) or
((Query_Down_Staff.State = dsEdit) and (Query_Temp.RecordCount > 0) and (Query_Down_Staff.FieldByName('S_NAME').NewValue <> Query_Down_Staff.FieldByName('S_NAME').OldValue)) then
begin
ShowMessage('此員工姓名已重複建立!');
Abort;
DBEdit1.SetFocus;
end;
end; 備註:
1.資料表的CachedUpdates要設定為True。
2.因為修改時,資料已經存在...所以要考慮修改時重複的問題。 發表人 - yenhorng 於 2004/09/20 13:15:16
|
cashxin2002
版主 發表:231 回覆:2555 積分:1937 註冊:2003-03-28 發送簡訊給我 |
您好﹗ 小弟的做法如下﹐截自于小弟某專案中﹐但是用ADO來存取﹐且沒有用到交易功能﹐您可自行變換或加入﹕
procedure TForm3.ADOTable1BeforePost(DataSet: TDataSet); Var IDRemark := String; begin IDRemark := Trim(ADOTable1.FieldByName('Idno').AsString); //將新輸入的Idno指定給IDRemark字串變數 ADOQuery1.Close; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('Select Idno From Employee '); ADOQuery1.SQL.Add('Where Idno=''' IDRemark ''' '); ADOQuery1.Open; if not ADOQuery1.IsEmpty then //當回值資料表不為空的時﹐有兩種現象﹐即ADOTable1是處于dsEdit狀態或是dsBrowse(等)非修改狀態 begin if ADOTable1.State <> dsEdit then //當ADOTable1處于dsBrowse等非修改狀態﹐可用值大于0來判斷 begin ShowMessage('該筆記錄重复﹗'); DBGrid1.SelectedIndex := 0; Abort(); end else //當ADOTable1為dsEdit修改狀態時﹐因被修改的資料本身已存在于資料表內﹐故要做大于1的判斷﹐而不是大于0的判斷 begin if ADOQuery1.RecordCount > 1 then begin ShowMessage('ID NO is repeat!'); DBGrid1.SelectedIndex := 0; Abort(); end; end; end; end;另外﹐建議您在做SQL的語法時﹐注意其語法中的空格﹐如您的程式碼中﹐沒有加空格的部分就比較容易出錯﹐如以下紅色下劃線處﹕ 1. Query2.sql.add('insert stock_(thing_no,much,money)_'); Query2.sql.add('value_(''' Table1.fields[0].asstring ''',''' Table1.fields[1].asstring''',''' Table1.fields[2].asstring ''')'); 2. Query2.sql.add('update stock set much=much ''' Table1.fields[1].asstring ''',money=money ''' Table1.fields[2].asstring '''_'); Query2.sql.add('where Thing_no=''' Table1.fields[0].asstring ''''); 個人建議﹐參考看看﹗ ========================= 大病初愈﹐休養調整中... =========================
------
忻晟 |
jacosun
一般會員 發表:42 回覆:64 積分:21 註冊:2003-04-18 發送簡訊給我 |
引言: 您好﹗ 小弟的做法如下﹐截自于小弟某專案中﹐但是用ADO來存取﹐且沒有用到交易功能﹐您可自行變換或加入﹕那如果說,若查無相同條件時新增,若查有相同條件時做updata的動作。也就是我的程式裡寫的1. Query2.sql.add('insert stock_(thing_no,much,money)_'); Query2.sql.add('value_(''' Table1.fields[0].asstring ''',''' Table1.fields[1].asstring''',''' Table1.fields[2].asstring ''')'); 2. Query2.sql.add('update stock set much=much ''' Table1.fields[1].asstring ''',money=money ''' Table1.fields[2].asstring '''_'); Query2.sql.add('where Thing_no=''' Table1.fields[0].asstring ''''); 這兩部份。 另外請教一下,在交易過程中,因為有Rollback是不是sql會把資料先暫存,等到都ok後再由commit做寫入動作。若是如此的話,我在交易的過程中再用select做查詢的話,是會查到交易前的資料表還是有做修正完的呢??procedure TForm3.ADOTable1BeforePost(DataSet: TDataSet); Var IDRemark := String; begin IDRemark := Trim(ADOTable1.FieldByName('Idno').AsString); //將新輸入的Idno指定給IDRemark字串變數 ADOQuery1.Close; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('Select Idno From Employee '); ADOQuery1.SQL.Add('Where Idno=''' IDRemark ''' '); ADOQuery1.Open; if not ADOQuery1.IsEmpty then //當回值資料表不為空的時﹐有兩種現象﹐即ADOTable1是處于dsEdit狀態或是dsBrowse(等)非修改狀態 begin if ADOTable1.State <> dsEdit then //當ADOTable1處于dsBrowse等非修改狀態﹐可用值大于0來判斷 begin ShowMessage('該筆記錄重复﹗'); DBGrid1.SelectedIndex := 0; Abort(); end else //當ADOTable1為dsEdit修改狀態時﹐因被修改的資料本身已存在于資料表內﹐故要做大于1的判斷﹐而不是大于0的判斷 begin if ADOQuery1.RecordCount > 1 then begin ShowMessage('ID NO is repeat!'); DBGrid1.SelectedIndex := 0; Abort(); end; end; end; end;另外﹐建議您在做SQL的語法時﹐注意其語法中的空格﹐如您的程式碼中﹐沒有加空格的部分就比較容易出錯﹐如以下紅色下劃線處﹕ 1. Query2.sql.add('insert stock_(thing_no,much,money)_'); Query2.sql.add('value_(''' Table1.fields[0].asstring ''',''' Table1.fields[1].asstring''',''' Table1.fields[2].asstring ''')'); 2. Query2.sql.add('update stock set much=much ''' Table1.fields[1].asstring ''',money=money ''' Table1.fields[2].asstring '''_'); Query2.sql.add('where Thing_no=''' Table1.fields[0].asstring ''''); 個人建議﹐參考看看﹗ ========================= 大病初愈﹐休養調整中... ========================= |
cashxin2002
版主 發表:231 回覆:2555 積分:1937 註冊:2003-03-28 發送簡訊給我 |
您好﹗ 1. 那如果說,若查無相同條件時新增,若查有相同條件時做updata的動作。也就是我的程式裡寫的1. Query2.sql.add('insert stock_(thing_no,much,money)_');
Query2.sql.add('value_('''+Table1.fields[0].asstring+''','''+Table1.fields[1].asstring''','''+Table1.fields[2].asstring+''')');
2. Query2.sql.add('update stock set much=much+'''+Table1.fields[1].asstring+''',money=money+'''+Table1.fields[2].asstring+'''_');
Query2.sql.add('where Thing_no='''+Table1.fields[0].asstring+'''');
這兩部份。
//答﹕單從語法上來看﹐應沒有問題﹒但請注意檢查一下資料形態部分的問題﹐如﹕您的Thing_no﹐much﹐money欄位都是字串形態嗎﹖因為之后update的語法中﹐是用原much和原money來加上指定的字串值(Table1.fields[2].asstring)(Table1.fields[2].asstring)﹐用Thing_no來做Update的判斷﹐所以若欄位形態不是字串形態的話﹐此SQL就會出錯﹒ 2. 另外請教一下,在交易過程中,因為有Rollback是不是sql會把資料先暫存,等到都ok後再由commit做寫入動作。若是如此的話,我在交易的過程中再用select做查詢的話,是會查到交易前的資料表還是有做修正完的呢??
//答﹕當您使用了StartTransaction方法后﹐在使用Rollback或Commit方法之前﹐所有資料的異動皆是在暫存狀態﹐但此時(交易過程中)再用Select做查詢的話﹐是會查到暫存狀態中的資料﹐即已經異動的資料內容﹒ =========================
大病初愈﹐休養調整中...
=========================
------
忻晟 |
yenhorng
中階會員 發表:12 回覆:82 積分:94 註冊:2002-06-18 發送簡訊給我 |
|
jacosun
一般會員 發表:42 回覆:64 積分:21 註冊:2003-04-18 發送簡訊給我 |
引言: 2. 另外請教一下,在交易過程中,因為有Rollback是不是sql會把資料先暫存,等到都ok後再由commit做寫入動作。若是如此的話,我在交易的過程中再用select做查詢的話,是會查到交易前的資料表還是有做修正完的呢?? //答﹕當您使用了StartTransaction方法后﹐在使用Rollback或Commit方法之前﹐所有資料的異動皆是在暫存狀態﹐但此時(交易過程中)再用Select做查詢的話﹐是會查到暫存狀態中的資料﹐即已經異動的資料內容﹒ ========================= 大病初愈﹐休養調整中... =========================以第二點來看,如果這樣的話。我之前有寫過這樣的程式碼如下 try Database1.startTransaction; Table1.first; while not Table1.eof do begin Query1.close; Query1.sql.clear; Query1.sql.add('select * from stock'); Query1.sql.add('where Thing_no = "' Table1.fields[0].asstring '"'); Query1.open; Query2.close; Query2.sql.clear; Query2.sql.add('update stock set much="' Query1.fields[1].asstring '" Table1.fields[1].asstring '",money=="' Query1.fields[1].asstring '" Table1.fields[1].asstring '"'); Query2.sql.add('where thing_no= "' Table1.fields[0].asstring '"'); Query2.execsql; Table1.next; end; DataBase1.commit; except DataBase1.rollback; end; 這樣只要在Table1裡的thing_no的值只要不重復,例如 thing_no much money 123 2 3 456 2 3 像這樣就沒問題,但是若是兩筆都是456的話就會發生錯誤.. 此時若把紅色的地方改為直接用updata就沒問題.....也就是 Query2.close; Query2.sql.clear; Query2.sql.add('updata stock set much=much "' Table1.field[1].asstring '",....'); Query2.sql.add('where Thing_no="' Table1.fields[0].asstring '"'); Query2.execsql; 我的疑問是即然是查修改的暫存,為何第一個程式就不能呢?? 感謝大大 |
cashxin2002
版主 發表:231 回覆:2555 積分:1937 註冊:2003-03-28 發送簡訊給我 |
引言: cashxin2002版主您好: 很抱歉,小弟麻煩您作個實驗! 如果您的資料庫內有3筆記錄如下 Idno欄位分別是 001 002 003 若您使用edit功能將第一筆記錄001改為003,不曉得可不可以儲存? 因為之前使用判斷式同您一樣,卻發生這個問題,謝謝.....您好﹗ 改成如下試試﹕ 增加一個內部宣告的字串變數﹕ Private {Public declarations} O_IDRemark : String; end; 在ADOTable1的BeforeEdit事件中﹕ procedure TForm3.ADOTable1BeforeEdit(DataSet: TDataSet); begin O_IDRemark := Trim(ADOTable1.FieldByName('Idno').AsString); end; 再加上如下紅色處﹕ procedure TForm3.ADOTable1BeforePost(DataSet: TDataSet); Var IDRemark := String; begin IDRemark := Trim(ADOTable1.FieldByName('Idno').AsString); ADOQuery1.Close; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('Select Idno From Employee '); ADOQuery1.SQL.Add('Where Idno=''' IDRemark ''' '); ADOQuery1.Open; if not ADOQuery1.IsEmpty then begin if ADOTable1.State <> dsEdit then begin ShowMessage('該筆記錄重复﹗'); DBGrid1.SelectedIndex := 0; Abort(); end else begin if ((ADOQuery1.RecordCount > 1) or (IDRemark <> O_IDRemark)) then begin ShowMessage('ID NO is repeat!'); DBGrid1.SelectedIndex := 0; Abort(); end; end; end; end;========================= 大病初愈﹐休養調整中... =========================
------
忻晟 |
cashxin2002
版主 發表:231 回覆:2555 積分:1937 註冊:2003-03-28 發送簡訊給我 |
引言: [quote] 以第二點來看,如果這樣的話。我之前有寫過這樣的程式碼如下 try Database1.startTransaction; Table1.first; while not Table1.eof do begin Query1.close; Query1.sql.clear; Query1.sql.add('select * from stock'); Query1.sql.add('where Thing_no = "' Table1.fields[0].asstring '"'); Query1.open; Query2.close; Query2.sql.clear; Query2.sql.add('update stock set much="' Query1.fields[1].asstring '" Table1.fields[1].asstring '",money=="' Query1.fields[1].asstring '" Table1.fields[1].asstring '"'); Query2.sql.add('where thing_no= "' Table1.fields[0].asstring '"'); Query2.execsql; Table1.next; end; DataBase1.commit; except DataBase1.rollback; end; 這樣只要在Table1裡的thing_no的值只要不重復,例如 thing_no much money 123 2 3 456 2 3 像這樣就沒問題,但是若是兩筆都是456的話就會發生錯誤.. 此時若把紅色的地方改為直接用updata就沒問題.....也就是 Query2.close; Query2.sql.clear; Query2.sql.add('updata stock set much=much "' Table1.field[1].asstring '",....'); Query2.sql.add('where Thing_no="' Table1.fields[0].asstring '"'); Query2.execsql; 我的疑問是即然是查修改的暫存,為何第一個程式就不能呢?? 感謝大大 >>< face="Verdana, Arial, Helvetica"> 您好﹗ 語法中有問題﹕ Query2.sql.add('update stock set much=''' Query1.fields[1].asstring ''' ''' Table1.fields[1].asstring ''',money=''' Query1.fields[1].asstring ''' ''' Table1.fields[1].asstring '''_');//紅色下劃線代表空格 Query2.sql.add('where thing_no= ''' Table1.fields[0].asstring ''''); 我覺得問題應是在既然Thing_no不是唯一索引欄位﹐那在Query1中的查詢結果也不一定只有一筆記錄﹐如果當查詢結果出現一筆以上的資料記錄時﹐Query2中的 Query1.fields[1].asstring Table1.fields[1].asstring 和 Query1.fields[1].asstring Table1.fields[1].asstring 語法中就不能确認使用Query1中對應Fields[1]的哪一筆記錄來做合計的計算動作﹒而直接使用第二種方法就可以避免這樣的問題了﹒ ========================= 大病初愈﹐休養調整中... =========================
------
忻晟 |
yenhorng
中階會員 發表:12 回覆:82 積分:94 註冊:2002-06-18 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |