線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1035
推到 Plurk!
推到 Facebook!

sql語法一句

尚未結案
jacosun
一般會員


發表:42
回覆:64
積分:21
註冊:2003-04-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-20 10:10:14 IP:61.59.xxx.xxx 未訂閱
程式碼如下 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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-20 12:01:13 IP:218.163.xxx.xxx 未訂閱
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包在裡面 資料庫怎會認得這是什麼東東 星期一,星期二...星期日..星期一..無窮迴圈@@
------
星期一,二...無窮迴圈@@
jacosun
一般會員


發表:42
回覆:64
積分:21
註冊:2003-04-18

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-20 12:48:57 IP:61.59.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-09-20 13:09:42 IP:220.143.xxx.xxx 未訂閱
為避免資料重複建立(索引唯一),我的作法如下,請參考: 使用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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-09-20 14:28:20 IP:202.62.xxx.xxx 未訂閱
您好﹗    小弟的做法如下﹐截自于小弟某專案中﹐但是用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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-09-20 17:36:43 IP:61.59.xxx.xxx 未訂閱
引言: 您好﹗ 小弟的做法如下﹐截自于小弟某專案中﹐但是用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 ''''); 個人建議﹐參考看看﹗ ========================= 大病初愈﹐休養調整中... =========================
那如果說,若查無相同條件時新增,若查有相同條件時做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做查詢的話,是會查到交易前的資料表還是有做修正完的呢??
cashxin2002
版主


發表:231
回覆:2555
積分:1937
註冊:2003-03-28

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-09-20 18:12:48 IP:202.62.xxx.xxx 未訂閱
您好﹗    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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-09-20 21:43:44 IP:220.143.xxx.xxx 未訂閱
cashxin2002版主您好: 很抱歉,小弟麻煩您作個實驗! 如果您的資料庫內有3筆記錄如下 Idno欄位分別是 001 002 003 若您使用edit功能將第一筆記錄001改為003,不曉得可不可以儲存? 因為之前使用判斷式同您一樣,卻發生這個問題,謝謝.....
jacosun
一般會員


發表:42
回覆:64
積分:21
註冊:2003-04-18

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-09-20 23:15:38 IP:221.169.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-09-21 09:50:08 IP:202.62.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-09-21 10:27:02 IP:202.62.xxx.xxx 未訂閱
引言: [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

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-09-22 23:23:24 IP:220.143.xxx.xxx 未訂閱
多謝 cashxin2002 版主指導....
系統時間:2024-07-07 2:34:18
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!