我爱builder

C++Builder 程序员博客

代码实现ADOQuery字段编辑器中Add All Fields功能,似乎不能实现,因为编译时需要确定Field的数据类型;
我想先把一个ADOQuery打开,然后再在另一个ADOQuery里加Fields,但是结果集为正确,还有其它好的解决方法吗?

//*.H文件
        TADOConnection *ADOConnection1;
        TADOQuery *ADOQuery1;
        TADOQuery *ADOQuery2;
        TDataSource *DataSource1;
        TDataSource *DataSource2;
        TDBGrid *DBGrid1;
        TDBGrid *DBGrid2;
//*.cpp文件
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add("select CategoryID, CategoryName, Description, Picture from Categories");
ADOQuery1->Open();

ADOQuery2->Close();
ADOQuery2->SQL->Clear();
ADOQuery2->SQL->Add("select CategoryID, CategoryName, Description, Picture from Categories");
//下面这里怎么才能实现与ADOQuery1数据集结果一样
for(int i=0;i <ADOQuery1->FieldCount;i++)
    ADOQuery2->Fields->Add(ADOQuery1->Fields->Fields[i]);
ADOQuery2->Open();

当然不是这样了,在ADOQuery2里面还能加入一些想要的字段的

搞不明白楼主想要什么。

用SQL语句as出来新字段不就行了。

拼SQL出来不就好了。

不明白lz的意思。
ADOQuery字段编辑器中Add All Fields不是把所有字段名都列出来么
和lz的代码完全不搭界啊。

  • Filed under: C++ Builder
  • ADOQuery空间是用new 动态创建的,想动态添加个计算的字段,网上找来的代码好像不行,也不知是自己不懂得如何弄

    C/C++ code
    TADOQuery *adoquery=new TADOQuery(NULL); adoquery->Connection=ADOConnection; adoquery->SQL->Text="select * from aaa"; adoquery->Open();

    主要想添加个用来表示记录序号的字段,我的想法是专门写个函数OnCalc(),然后adoquery->OnCalcFields=onCalc;但是不知道该如何添加这个动态计算的字段,希望搞过这个的高手指点迷津,在此谢过啦

      ADOQuery1->Close();
      ADOQuery1->SQL->Text = "select .  ";
      TStringField *F = new TStringField(this);
      F->FieldName = "Order";
      F->DataSet = ADOQuery1;
      F->FieldKind = fkCalculated;
      ADOQuery1->Open;

    引用 2 楼 jjwwang 的回复:
      ADOQuery1->Close();
      ADOQuery1->SQL->Text = "select .  ";
      TStringField *F = new TStringField(this);
      F->FieldName = "Order";
      F->DataSet = ADOQuery1;
      F->FieldKind = fkCalculated;
      ADOQuery1->Open;

    你好啊,这方法我刚试过,我把SQL改为select * from aaa,然后用你的这个方面,那么查出来的结果集中在表格里面只显示了这个Order的字段,其他我表中的子都都没有显示出来,不知道怎么回事

    DataSet一旦Open , 是不允許修改字段列表的。
    要自定義字段列表,是有些無奈。
    1、通過另一個DataSet 用 select top  0 * from table 取得字段列表。
      TADOQuery *tmpds=new TADOQuery(NULL);
      tmpds->Connection=ADOConnection;
      tmpds->SQL->Text="select top 0 * from aaa";
      tmpds->Open();
    2、為目的DataSet構造需要的字段。
      TADOQuery *adoquery=new TADOQuery(NULL);
      adoquery->Connection=ADOConnection;
      //生成應有的字段
      TFieldDefs *pDefs = adoquery->FieldDefs;
      pDefs->BeginUpdate();
      for(int i = 0 ; i < tmpds->FieldCount ; ++i)
      {
        TField *f = tmpds->Fields->Fields[i];
        TFieldDef *pDef  = pDefs->AddFieldDef();
    pDef->Name = f->FieldName;
    pDef->DataType = f->DataType;
    pDef->Size =  f->Size;
        f = pDef->CreateField(adoquery);
        …這裡可以設定字段f的各種屬性     
      }
      delete tmpds ;
      pDefs->EndUpdate();
      //然後加入自己額外的字段(計算字段或Lookup字段),需要的話可以設定各個字段的屬性。 
    ….
      //最後設定SQL並打開數據庫
      adoquery->SQL->Text="select * from aaa";
      adoquery->Open();

    大概過程就是這樣。具體代碼請自行調試。這樣建立的字段列表,並不會隨著 DataSet->Close() 而被清空。

    這過程代碼比較多,不知道是否有更簡潔的方式來達到同樣的目的。

    我在网上找了端代码,但是不知道该如何去调用,测试了好几次都出现异常,代码如下:
    [code=C/C++]
        void       __fastcall       TForm1::AddCalcField(String       FdName,       TADOQuery   *DSName,       TStringField       *dt)      
        {      
                static       count       =       0;      
                if(       DSName-> FindField(FdName)!=       NULL)      
                            return;      
                DSName-> Close();      
                try      
                {      
                        dt       =       new       TStringField(DSName);      
                        {      
           
                                dt-> FieldName       =       FdName;      
                                dt-> DisplayLabel       =       FdName;      
                                dt-> FieldKind       =       fkCalculated;      
                                dt-> Name       =       "Field "       +       String(count++);      
                                dt-> Index       =       DSName-> FieldCount;      
                                dt-> DataSet       =       DSName;      
                                DSName-> FieldDefs-> Update();      
                        }      
                }      
                catch(Exception       &e)      
                {      
                        ShowMessage(e.Message);      
                }      
        }
    [/code]
    我是这样调用的:
    [code=C/C++]
            adoquery=new   TADOQuery(NULL);
            adoquery-> Connection=ADOConnection;
            adoquery-> Close();
            adoquery-> SQL-> Text= "select   *   from   aaa ";
            TStringField       *dt;
            AddCalcField( "Order ",adoquery,dt);
            adoquery-> OnCalcFields=onCalc;
            adoquery-> Open();
    [/code]
        但是不行,并且在关系程序时出现异常,郁闷……

    C/C++ code
    void __fastcall OnCalc() { adoquery->FieldByName("Order")->AsString=IntToStr(adoquery->RecNo); }

    引用 4 楼 PPower 的回复:
    DataSet一旦Open , 是不允許修改字段列表的。
    要自定義字段列表,是有些無奈。
    1、通過另一個DataSet 用 select top  0 * from table 取得字段列表。
      TADOQuery *tmpds=new TADOQuery(NULL);
      tmpds->Connection=ADOConnection;
      tmpds->SQL->Text="select top 0 * from aaa";
      tmpds->Open();
    2、為目的DataSet構造需要的字段。
      TADOQuery *adoquery=new TADOQuery(NULL);
      adoquery->Connection=ADO…

    这个解释的详细,我来学习了

    在设计时上双击ADOQuery1, 你先手工加上你需要的字段.(省点事. 要不然你还要写代码一个字段一个字段的加.)

    然后再程序中加入我的代码. 就OK了.

      ADOQuery1->Close();
      ADOQuery1->SQL->Text = "select .  ";

      //另外先判断一下
      TField *F = ADOQuery1->FindField("Order");
      if F=NULL then
      {
        TStringField *F = new TStringField(this);
        F->FieldName = "Order";
        F->DataSet = ADOQuery1;
        F->FieldKind = fkCalculated;
      }
      ADOQuery1->Open;

    晕.写DELPHI代码习惯了.

      ADOQuery1->Close();
      ADOQuery1->SQL->Text = "select .  ";

      //另外先判断一下
      TField *F = ADOQuery1->FindField("Order");
      if (F=NULL)  {
        TStringField *F = new TStringField(this);
        F->FieldName = "Order";
        F->DataSet = ADOQuery1;
        F->FieldKind = fkCalculated;
      }
      ADOQuery1->Open;

    TO: w88529593
      你在5楼的代碼,應該是設計期已經固化了字段列表,然後在這個基礎上再加上一個計算字段,但你的情況是:SQL是後期再加上的,字段列表是空的,設計期沒有辦法固死字段列表。
      注意一下代碼需要的應用環境就行了。編程不能只會COPY代碼的。

    我說的與 jjwwang 說的意思基本一致。

    或许目前除了构造两个TADOQuery对象,然后将一个adoquery->Open后,遍历其字段列表添加到另一个adoquery里面,然后再把动态计算的字段也添加进去,暂时没其他更好的方法了,那就这样了

  • Filed under: C++ Builder
  • AnsiString tmpSQL ="select b.code,b.Age,b.AgeUnit,b.Name,b.Gender,b.mdate,b.mtime from ";
    tmpSQL+="Patient b where b.id='"+patID+"'";
    ADOQuery1->Close();
    ADOQuery1->SQL->Clear();
    ADOQuery1->SQL->Add(tmpSQL);
    ADOQuery1->Open();
    上面的程序一运行就出现期待数是3,而我只有1.

    就是运行时出来的,我的程序有问题吗,ADOQuery还需要设置什么吗

    期待數…錯誤提示信息是什麽
    是搜不出來數據還是搜出來的數據不對
    ADO不用設置什麽
    就是上面的寫法 指定一下connection

    到查询分析器里面去用你SQL验证下结果吧
    应该和Query无关。可能是你SQL语句问题

    Project Project1.exe raised exception class EOleException with message'[Microsoft][ODBC Microsoft Access Driver]参数不足,期待是3。'
    运行程序出现上面的东西

  • Filed under: C++ Builder
  • 因为数据库中有一个文本型的Field,
    我要判断这个Field的值是否符合要求,
    没法用SQL语句来选择,
    而且数据量不是很多,
    所以想用代码一条一条地判断,
    符合的就在DBGrid中显示。
    不知有什么办法可以实现?

      怎么会没法用SQL语句判断呢?

    C/C++ code
    void __fastcall TForm1::ADOQuery1FilterRecord(TDataSet *DataSet, bool &Accept) { //这里写上你过滤的代码,比如你可以在那个‘text’类型字段中搜索某个你认为的关键的东东 搜索到了就让 Accept= true; Accept = IsIWant(….) ;// 。。 } //—————————————————————————

    谢谢jxw1987628,问题解决了。

    另外,
    hnzlk:
    我的数据库有一个Field,
    用来保存温度的,
    而如果温度传感器不接或短路时,
    这个Field里的值不是一个数值,
    而是“断线”或“短路”这样的文本,
    所以我只能把这个Field定义为文本型。
    这样的话怎么用SQL去筛选温度值大于30度而小于50度的记录呢?
    可另开帖给分。

    顶小漫
    ADOQuery1->Filtered=true;

    怎么用SQL去筛选温度值大于30度而小于50度的记录呢
    select * from 表
    where case when isnumeric(温度)=1 then cast(温度 as float) else 0 end between 30 and 50

  • Filed under: C++ Builder
  • [ADOQuery]ADOQuery求助

    ADOQuery->SQL->Add("SELECT * FROM  hmfb WHERE  N01= :JHP1 or N02 = :JHP1 or N03= :JHP1 ");
    ADOQuery->Parameters->ParamByName("JHP1")->Value=ComboBox1->Text;

    程序如上,我想这样找,但只能找到满足N01的,其它不行,请帮分析下应该怎么改一下.

    参数名称最好区分一下,不要重名,否则会被更名。

    C/C++ code
    // 嗯 ,后面的N02 N03 的对应的 JHP1 换成其他不一样的变量 如JHP2 ,JHP3 // 然后再给JHP2 ,JHP3也赋上值

    多谢僵哥!

  • Filed under: C++ Builder
  • 环境:frameA镶嵌在formA上,formB是另一个form
    frameA上有一个DBGrid
    formB上用了adoquery进行数据库存储

    问题是

    DBGrid怎么连接到adoquery进行数据库显示?是不是要额外加一个adoquery来负责DBGrid的显示?还有,不用DataSource行吗?觉得这个中间人麻烦,所以不想用他。

    没有中间人介绍,无法直接恋爱!

    引用 2 楼 i_love_pc 的回复:
    没有中间人介绍,无法直接恋爱!

    意思说必须通过DataSource?这个东西是干么事的啊?

    作媒的

    BCB中是这样说的
    Use TDataSource to

    provide a conduit between a dataset and data-aware controls on a form that enable display, navigation, and editing of the data underlying the dataset.
    link two datasets in a master/detail relationship.

    All datasets must be associated with a data source component if their data is to be displayed and manipulated in data-aware controls. Similarly, each data-aware control needs to be associated with a data source component in order for the control to receive and manipulate data.

    Data source components also link datasets in master-detail relationships.

    数据感知控件…必须有…

    通过这个,你的DBGIRD才知道这一列写什么数据

    C/C++ code
    /* 数据源呀,不然DBGrid从哪搞数据,当然你可以直接从Query中读取数据到某个 Grid中显示,那样你可以用它的胞弟控件TStringGrid,但是这样就需要你去 写数据读取代码,刷新代码,还有编辑,更新等代码。而如果你用DBGrid来帮 你,那么可以省去你很多的代码! */

  • Filed under: C++ Builder
  • [color=#0000FF]曾将DBGird连接ADOQuery ,DBGird闪得难受,不知还有什么方法?[/color]

    DBGird连接ADOTable , ADOQuery修改数据,
    怎么让DBGird实时显示修改后的数据?

    DBGird一直连接ADOTable , ADOQuery就可以了嘛,修改后数据POST(),自动显示上了啊!

  • Filed under: C++ Builder
  • 用户服务器上装的是oracle 11g,但没有客户端,
    我在网上查了下,用ado连接oracle大概有两种方法,一种直接连客户端,但无论是ole db provider for oracle还是oracle provider for ole db,都需要有客户端,在网上也没有找到有11g的客户端;
    另一种是建立odbc数据源,然后连数据源,建立odbc数据源可以了,测试连接也通过了,但用ado连接那个数据源的时候,提示未发现数据源名称并且未指定默认驱动器,adoquery的connectionstring是Provider=MSDASQL.1;Persist Security Info=False;User ID=ccc;Data Source=aaa,aaa是建立的数据源的dsn,这是怎么回事呢?如何解决?

    我是这样的
    1.装oracle客户端,用oracle驱动
    2.用微软对oracle支持的驱动 Microsoft Ole DB Provider for oracle
    (装了MDAC就有了)

    1.装oracle客户端,用oracle驱动
    2.用微软对oracle支持的驱动 Microsoft Ole DB Provider for oracle
    (装了MDAC就有了)
    —–只能这样了。个人建议安装客户端好些

    UP

    ORACLE 自带的 OLEDB 客户端是很大很笨重的, 简直是牛魔王

    个人建议安装客户端好些

    引用 3 楼 hmh780210 的回复:
    1.装oracle客户端,用oracle驱动
    2.用微软对oracle支持的驱动 Microsoft Ole DB Provider for oracle
    (装了MDAC就有了)
    —–只能这样了。个人建议安装客户端好些

    网上有个精简客户端下载的.如果你在客户端不需要特别的处理,那个精简客户端足够满足你了.

    Oracle 无论如何都自带客户端的,安装时你可以注意看一下,实际上就是几个DLL,创建可以透过ODBC连接Oracle的驱动,也可以用ADO直接连接Oracle驱动,建议后者。

    用Microsoft OleDB Provider For Oracle !

    来晚了点..一般安装驱动是可以的..

  • Filed under: C++ Builder
  • 因为我要在极短的时间间隔里面,例如500毫秒或者是100毫秒不断的刷新或者是提取数据库记录,ADOQuery能否设置同步或者异步的工作形式

    ADOQuery 本来就是同步的 Borland已经封装好的

    引用 2 楼 fangsp 的回复:
    ADOQuery 本来就是同步的 Borland已经封装好的

    真的吗?好象不是吧… … :)

  • Filed under: C++ Builder
  •       str="select ppa=:ppa from yuechan where ";
          str=str+"farm";
          str=str+"=:queryitem";
          query->Close();
          query->SQL->Clear();
          query->SQL->Add(str);
          query->Parameters->ParamByName("queryitem")->Value=FastCode->Text;
          query->Prepared=true;
          query->Open();
          str1=query->FieldByName("ppa")->AsString;
          这样可以将一条记录保存到str1中

          但是,如果query后得到的是多条记录,那我该怎样将他们保存起来呢?
          比如,query后得到的了三条记录:
          xiaozhang
        xiaowang
        xiaoli
        该怎么保存呢?
          是用dataset么?
          哪位高手指点一下呀,我快郁闷死了,明天就要交了
          另外能详细点说么,我是新手,用的不太熟练

    ADOQuery->FieldByName("Name")->Value就可以取出ADOQuery的某个字段值,当然你还须使用循环一条一条的选。

    或者用select 选到的结果 into另一张空表~ 就保存啦~

    补充一下:
    (select into from)要求目标表(destTbl)不存在,因为在插入时会自动创建。

    谢了,还有个问题我访问的数据表是vfp的表,这时我在select语句中加入参数:ppa(str="select ppa=:ppa from yuechan where "; )就会报错,去掉参数就没问题了,有人说这是因为在bcb中访问vfp必须用vfp的语法才行,请问这种情况怎么将参数传出来呀

    还有,三楼的方法,我试了一下 为什么不能产生新表呀:
    select bm into dbf d:\\sebm from ksjq where
    还有我希望将结果放到一个sql表中,应该怎么写呀

    产生的新表在SQLserver数据库里面~~

    最好还是像2楼说的,用本地变量保存起来就可以了

    但是,问题我访问的数据表是vfp的表,这时我在select语句中加入参数:ppa(str="select ppa=:ppa from yuechan where "; )就会报错,去掉参数就没问题了,有人说这是因为在bcb中访问vfp必须用vfp的语法才行,请问这种情况怎么将参数传出来呀

    回7楼,具体名令怎么写呀比如想将表保存到名为aa的sql表中

    select 内容 into aa

    BCB格式应该这样:
    SELECT  *  INTO  '2222.DB'  FROM  '1111.DB' 
      WHERE    条件

    insert into 222 select * from 111 where 条件

    问题解决了,谢谢大家了,:p

    q贴出来看看 怎么解决滴~~

  • Filed under: C++ Builder