小妹的毕业设计眼看就要交了,可是一个问题始终解决不了。问了好几个师兄都没没辙。情急之下,只好来这里求教高人。问题简述如下:delphi和oracle之间采用BDE连接。对于oracle下的表ziliao进行删除操作。控件是
datasoure,table,一个edit1,用于输入想删除的记录的名字,一个button按钮。
单击button,加入代码procedure TForm1.Button1Click(Sender: TObject);
begin
    with table1 do
    begin
     indexfieldnames:='article_name';
     if findkey([edit1.text])then
     begin
      if messagedlg('你确定要删除这条记录么',mtconfirmation,[mbyes,mbno],0)=mryes then delete;
     end
    else
       messagedlg('没有找到该纪录',mterror,[mbcancel],0);
    end;
end;程序运行后,在edit1中输入想删除的文章的名字,点击按钮弹出“你确定要删除这条记录么”的box,至此都正确,可是当点击确定按钮后,即报错:prject delproject1.exe raised exception class EAccessViolation with message'Access violation at address 4DAO64AD in module 'IDODBC32.DLL'.Read of address 00000014'.若后台数据库不用oracle,譬如以delphi自带的DBDEMOS,同样的程序,运行起来就没有问题。初步怀疑是BDE的问题,要不就是我的电脑太烂了?求教,求教,再解决不了,真要郁闷死了!

解决方案 »

  1.   

    :(
    换种定位方式试试:
    with table1 do
        begin
         if locate('article_name',trim(edit1.text),[locaseinsensitive])then
         begin
          if messagedlg('你确定要删除这条记录么',mtconfirmation,[mbyes,mbno],0)=mryes then delete;
         end
        else
           messagedlg('没有找到该纪录',mterror,[mbcancel],0);
        end;
      

  2.   

    若weitao999(涛涛)的不行,干脆用存储函数据吧,试试这样:
    在oracle中;
     create or replace procedure delete_record(,tablename in varchar2,fieldname in varchar2)
     as
      v_sql :varchar2;
    begin
      v_sql:='delete from  '||tablename||' where 'article_name= '|| fieldname;
      execute immediate v_sql;
      commit;
    end   delete_record;
    /
    在delphi中用adostoredproc 调用!
      

  3.   

    sorry!delete_record中多了一个‘,’;
      

  4.   

    taotao,请问你的方法和table.locate('article_name',edit1.text,[]);这样写有什么不同?
      

  5.   

    pingshx() ,我的oracle用得很不熟,只是建了一个数据库,一个表而已
    你说的那些语句是在sql&plus里输入还是…………
      

  6.   

    你对这个表建立一个主索引就可以了,findkey必须要求有主索引,而且好像在locate的时候也会报错,我记得错好像就是这个,我曾经操作oracle也碰到了同样的问题,后来加了主索引就可以了!
      

  7.   

    ake1980(阿柯) 还有,你刚才说得那个locate的写法和涛涛的写法区别在于比队的时候是否区别大小些,默认值好像是不区分的,忘了,你可以查帮助
      

  8.   

    用 TQuery + SQL:procedure TForm1.Button1Click(Sender: TObject);
    var
      exists: Boolean;
    begin
      query1.sql.text := 'select article_name from '+table1.tablename+' where article_name=:article_name';
      query1.parambyname('article_name').asstring := edit1.text;
      query1.open;
      exits := not query1.eof;
      query1.close;
      if exists then
      begin
        if messagedlg('你确定要删除这条记录么',mtconfirmation,[mbyes,mbno],0)=mryes then 
        begin
          query1.sql.text := 'delete from '+table1.tablename+' where article_name=:article_name';
          query1.parambyname('article_name').asstring := edit1.text;
          query1.execsql;
          table1.refresh;
        end;
      end
      else
         messagedlg('没有找到该纪录',mterror,[mbcancel],0);end;另外,好象你是用ODBC连接的,其实用BDE可以直接连接,没有必要通过ODBC的。祝:好运!
      

  9.   

    BDE可能对oralce支持不够,换个方式看看
      

  10.   

    agui(阿贵 as 三楼的楼长) 的方法依然不可以.我也发现BDE很烂,但是改也来不及了。居然还要在论文里说BDE好,ft
      

  11.   

    非常感谢大家的帮助。在按照 gardenyang(太阳雨) 说的,建立了主索引之后问题解决了:)
    可是findkey和locate只能定位一条记录。我现在想把程序改进一下,用TQuery+SQL,看了这个帖子《BDE+ORACLE,TQuery的RequestLive不能设为True?》(http://expert.csdn.net/Expert/topic/1815/1815503.xml?temp=.6293909),我发现,想让其完成查找后再修改的功能几乎实现不了,语句如下:procedure TForm1.button1Click(Sender: TObject);
    begin
           strsql:='select * from ZILIAO where author like '''+'%'+trim(edit1.Text)+'%'+'''';
            query1.Close;
            query1.sql.Clear;
            query1.SQL.Add(strsql);
            try
            query1.Open;
            except
            query1.ExecSQL;
            end;
    end;是不是这样写无论如何也无法对返回的数据进行操作?
    如果我想对返回的查找条目进行操作,怎样才可以呢?
      

  12.   

    是在sql*plus中输入的,还有我的函数有点问题:说明变时多了一个‘:’,应没有‘:’,
    把它当成D了,
      

  13.   

    阿柯,其实你用了query1.open即使报错了,跳入到except中,它也已经执行了,所以你不用再except中再进行query1.execsql了
    try
      query1.open;//此时不管是否返回结果,query1都已经执行了。就是说如果是update语句,
                  //也已经执行完了
    except
    end; 
    另外我认为requestalive设置true后应该可以修改结果集,如果不行可以改用两个query实现,一个query查询一个进行update
      

  14.   

    太阳雨,我把requestalive设置成true后,报错,说表或视图不存在。关于excesql的用法,我看书上说“如果调用open方法,而没有查询结果时,会出错。此时应该用exessql方法来代替open方法。”我理解的“没有查询结果”是说,比如我查找author,结果没有查到相对的记录,就算是“没有查询结果”,这完全有可能发生。那么
    except 
       query1.execsql
    语句就是必须的了。但是按照你说的,我删掉了该语句。即便没有查到相对的记录,程序依旧可以运行。那么execsql语句到底有什么用呢?我希望修改Query部件返回的只读的查询结果集。在一本书上看到一个方法:"在应用程序中另外增加一个Query部件Query2;在Query2中设置修改语句upDATe对query1中的数据进行操作".和你说的一样。我还没有用过两个query,挺抽象的,理解不了。能给个小demo么?谢谢了
      

  15.   

    还是在这里也写一下吧,大家也能给我一些建议!
    query1.open所要干的事情是:首先执行查询语句(类似query1.execsql),然后获取结果集(类似fetch recordset),所以你except里面不需要在写一遍query1.execsql。
    那个demo的问题:
    query1.sql.text:='select key from table1 where case1';其中key是你的primary key的fieldname,case是你的定位条件。
    query1.open;
    query2.sql.text:='update table1 set ..... where key='+query1.fields[0].asstring;
    query2.execsql;
    这样就可以了;
    或者用clone可能也可以,不过建议你还是用上面的办法,另外需要注意的是,在query2的更新操作过程中不能改变primary key的值。