数据库问题,急

时间:2021-09-12 20:49:46
我用bcb做一个进销存系统,这里有一个form,有一些query,datasource,DBEdit,DBComboBox,一个DBGrid,四个
bitbtn,其中DEEdit和DBComboBox元件都和指定的Datasource连好,DBGrid连的datasource和DEEdit和DBCombobox是同一个datasource。当这个Form在showModal()时,就会
void __fastcall TForm2::FormCreate(TObject *Sender)
{               Form2->Query1->Insert();
Form2->Query1BDEDesigner14->Value=Form2->Query1->RecordCount+1;

};//query1所连的表的主键值自动加一,不会使主键重复
这里出了一个问题,就是如果这个Form弹出时其它的DBEdit和DBcombobox都为空,当我用鼠标点击DBGrid时,其它的DBEdit和DBComboBox也会跟着变成dbgrid上的记录,可我还未post,发觉数据库里这个table的记录就自动加一,能否使Query1->Post();才使数据表记录增加?

45 个解决方案

#1


你用这种方法来实现字段自动增加不妥;因为你如果删除一条记录后在增加,有可能出现
主键重复。
 解决方法:
 1. 你如果你的数据库支持自增字段,可使用自增字段(如Paradox,SQLSERVER)
 2.如果不支持你应该判断该字段的最大值,如Max(Field1)+1  (此处用SQL语言实现)
 3.还可以用触发器,和生成器来实现。

然后说说DBEdit的问题,你如果不想在DBEdit中编辑和提交数据库,将DBEdit设为ReadOnly=true;手动控制数据库的添加,和保存功能。

#2


不好意思上面有错,该为
然后说说DBGrid的问题,你如果不想在DBGrid中编辑和提交数据库,将DBGrid设为ReadOnly=true;手动控制数据库的添加,和保存功能。 

#3


dbgrid的readonly=true我试过了,不行

#4


我的意思是你不要在FormCreate事件中插入数据,用别的方法如添加一个插入的按钮和一个
保存的按钮。用按钮来操作数据库。

#5


而且我就是要用DBEdit来提交记录

#6


请问大哥你的第一个解决方案具体如何?

#7


是这样的你的DBEdit,DBGrid绑定的是同一个数据集Query1,他们肯定是同步的。

#8


你的数据库是什么?

#9


sqlserver,很感谢你,真的

#10


SQLSQER支持自增型字段,不用你输入,你查一查资料吧,很简单的。

#11


困惑

#12


你添加数据时,自增型字段的值不用你输入,它的值按照步长自动增加。

#13


在SQLSERVER2000中设置自增型字段:
在表设计器中将某列的:标示选为“是”,种子选为“1”,标示递增量选为“1”;
这样以后就表明,当你向表中添加数据时,该列的值自动增加。
  如:
  1
  2
  3
  4
  .
  .
  

#14


如果我只是用Query1->Insert();
根本是不能的,会报错,因为主键会重复

#15


你的Query1的SQL是如何写的

#16


对不起,我最后的答复稍比你的倒数第二次答复来得早,我试过你的方法,可以。但有个小问题,就是如果我新增数据后,我再到sqlserver的企业管理器的这个数据表单把刚刚增加的记录删除,
第二次再用这个form新增数据,再到sqlserver的企业管理器的这个数据表再看,第二次新增数据的记录的主键值跳了一个数,像
1
2
3
5

#17


这样也没有错,因为你删除了一条记录。这样主键不会重复。

#18


谢谢你,我想再问你一个问题
现在我想在上面的DBEdit控件添加一些内容后按一个button按钮后使这些DBEdit控件
的值传到下面的DGird1控件,而不显示DBGrid1所连的数据集元件以前的记录,只显示
现在新增的记录,但可使这个Query1所连的表可自动加上前面添加的记录,DBGrid1所
连的datasource和dbedit,dbcombobox所连的是同一个

#19


我不太明白你的意思。

#20


你的伊妹是多少,我发个form给你呀,只有20k.

#21


压缩了只有几K

#22


xucoh@hotmail.com

#23


发了

#24


邮件收到,你看我理解得对不对:你想DBGrid1只显示新添加的记录是不是。

#25


是呀

#26


我有一个简单的方法:你将DBGrid1的高度调到只能显示一条记录。

#27


可否有第二个方法,因为用户可能要再添加记录。高度太小可能不太好

#28


那你不要用DBGrid来显示,用ListView,数据库添加一条,ListView插入一条。
窗体关闭时ListView->Items->Clear();

#29


具体的程序可否写给我看啊

#30


我写一个大体吧:(只針對ListView的操作)

  1.在窗体的onshow事件中加入
     ListView->Items->Clear();
  2.在Query1提交后加入
     TListItem* LI;
     LI=ListView1->Items->Add();
     LI->Caption=Query1BDEDesigner4->Value;
     LI->SubItems->Add(Query1BDEDesigner5->Value)   
     LI->SubItems->Add(IntToStr(Query1BDEDesigner6->Valu))//假如你的数量时整型
     其他的代码自己加吧
     关闭窗体时要delete LI;

#31


请问除了用ListView外,还有别的方法吗?我按你的方法用过listview,不甚理想。请

#32


想一想

#33


请问你是不是用adsl的?

#34


我用的宽带。1M

#35


这样就ok了,我发过程序给你,这个程序做得很好,我上面的这个带grid的form是模仿它的,你看有否办法

#36


如果>1M,请发到xucoh@163.com

#37


发了

#38


hotxu哥,等你答复,有答案望赐教小弟

#39


我还没有收到。

#40


关注。。。

#41


可以按照,主键排序,然后作一个循环,找到主键中没有的数据,作为主键
如果1,2,5,7,则找到3作为主键

#42


3个控件都是同样的datasourse ,你有不给出语句中断,当然会出现你所说的情况啊!

#43


我用DELPHI的,不过DELPHI和BCB很多地方类似 ,不知道能不能帮上你的忙:

如果你的数据库里面的字段没有加上非空约束的话,每次你用ShowModal()都调用Insert(),自然会在在数据库中添加一条记录,只不过该记录的主键是你定义的递增值,而其他字段为空.所以你的FORM显示的时候其他数据控件都是空的.
而你点DBGRID的时候自然是选择了其中一个记录,这样QUERY控件的游标就定义到这个记录上,自然其他与这个QUERY连接的数据控件要显示这条记录了.

另外你如果设置DBGRID的READONLY后,由于调用的是QUERY的INSERT,跟DBGRID一点关系没有,怎么能好使呢??????  DBGRID的READONLY只对在该DBGRID上进行的修改操作有效,对越过DBGRID直接操作QUERY 当然无能为力了,所以要用属性控制只读,也只能控制QUERY 的类似属性,好象叫CanModify吧!

下面进入正题:
BDE用一种称为立即更新(记不清叫什么名字了)的技术,即你一旦对界面上的数据控件(DBEdit,DBGrid等)进行修改,数据马上从本地缓存(实际上就是Query控件)发往数据库进行更新.所以你一调用INSERT()就马上生效.
这一机制有它方便的地方,就是UPDATE的时候几乎不用程序员编写另外的代码;但有不好的地方,即INSERT的时候不方便,以DBGRID为例,当在字段间移动(列方向)时不更新,仅当你移动记录游标时(行方向上的选择)进行更新,这是为了保持同一记录的完整性;但如果要求几条记录同时更新或插入,否则滚回(ROLLBACK)的时候这个就成为了障碍.所以有另外的方法,即动态更新.
动态更新主要用于C/S结构,为减少通信量和其他特殊的控制而使用.当使用这一机制的时候,每当你修改数据,只是修改本地缓存的数据,只有你在程序里显式调用UPDATE方法才把更新反映到数据库中,这样减少了即时更新时每次修改都与SERVER连接的通信量,也叫"需要时更新",当然这要和DELPHI的异常控制和TRY EXCEPT,ROLLBACK一起使用以保证数据库完整性.具体使用控件是UpdateSQL和TDataSet的子类(QUERY等),其中具体的设置见DELPHI帮助,里面还有完整的例子,只不过是英文的,耐心一点就看懂了.这个方法很强大,代价是麻烦一点.所以万不得已当然不用了.

以你的情况来看,根本没必要用,SQLSERVER自己有自增字段的,很好用.1235的问题也不必考虑,主键又没说必须要连续的数字的,为了美观而搞出那么多麻烦事没必要.

以上对DELPHI是肯定的,BCB还要自己去查一下.小弟好长时间没作程序了,具体的名字记得不准确的话大家不要扔柿子啊!

#44


多谢,多谢大哥,多谢前辈指点

#45


说错了,QUERY组件的只读是由RequestLive属性控制的,
TABLE是由READONLY.

#1


你用这种方法来实现字段自动增加不妥;因为你如果删除一条记录后在增加,有可能出现
主键重复。
 解决方法:
 1. 你如果你的数据库支持自增字段,可使用自增字段(如Paradox,SQLSERVER)
 2.如果不支持你应该判断该字段的最大值,如Max(Field1)+1  (此处用SQL语言实现)
 3.还可以用触发器,和生成器来实现。

然后说说DBEdit的问题,你如果不想在DBEdit中编辑和提交数据库,将DBEdit设为ReadOnly=true;手动控制数据库的添加,和保存功能。

#2


不好意思上面有错,该为
然后说说DBGrid的问题,你如果不想在DBGrid中编辑和提交数据库,将DBGrid设为ReadOnly=true;手动控制数据库的添加,和保存功能。 

#3


dbgrid的readonly=true我试过了,不行

#4


我的意思是你不要在FormCreate事件中插入数据,用别的方法如添加一个插入的按钮和一个
保存的按钮。用按钮来操作数据库。

#5


而且我就是要用DBEdit来提交记录

#6


请问大哥你的第一个解决方案具体如何?

#7


是这样的你的DBEdit,DBGrid绑定的是同一个数据集Query1,他们肯定是同步的。

#8


你的数据库是什么?

#9


sqlserver,很感谢你,真的

#10


SQLSQER支持自增型字段,不用你输入,你查一查资料吧,很简单的。

#11


困惑

#12


你添加数据时,自增型字段的值不用你输入,它的值按照步长自动增加。

#13


在SQLSERVER2000中设置自增型字段:
在表设计器中将某列的:标示选为“是”,种子选为“1”,标示递增量选为“1”;
这样以后就表明,当你向表中添加数据时,该列的值自动增加。
  如:
  1
  2
  3
  4
  .
  .
  

#14


如果我只是用Query1->Insert();
根本是不能的,会报错,因为主键会重复

#15


你的Query1的SQL是如何写的

#16


对不起,我最后的答复稍比你的倒数第二次答复来得早,我试过你的方法,可以。但有个小问题,就是如果我新增数据后,我再到sqlserver的企业管理器的这个数据表单把刚刚增加的记录删除,
第二次再用这个form新增数据,再到sqlserver的企业管理器的这个数据表再看,第二次新增数据的记录的主键值跳了一个数,像
1
2
3
5

#17


这样也没有错,因为你删除了一条记录。这样主键不会重复。

#18


谢谢你,我想再问你一个问题
现在我想在上面的DBEdit控件添加一些内容后按一个button按钮后使这些DBEdit控件
的值传到下面的DGird1控件,而不显示DBGrid1所连的数据集元件以前的记录,只显示
现在新增的记录,但可使这个Query1所连的表可自动加上前面添加的记录,DBGrid1所
连的datasource和dbedit,dbcombobox所连的是同一个

#19


我不太明白你的意思。

#20


你的伊妹是多少,我发个form给你呀,只有20k.

#21


压缩了只有几K

#22


xucoh@hotmail.com

#23


发了

#24


邮件收到,你看我理解得对不对:你想DBGrid1只显示新添加的记录是不是。

#25


是呀

#26


我有一个简单的方法:你将DBGrid1的高度调到只能显示一条记录。

#27


可否有第二个方法,因为用户可能要再添加记录。高度太小可能不太好

#28


那你不要用DBGrid来显示,用ListView,数据库添加一条,ListView插入一条。
窗体关闭时ListView->Items->Clear();

#29


具体的程序可否写给我看啊

#30


我写一个大体吧:(只針對ListView的操作)

  1.在窗体的onshow事件中加入
     ListView->Items->Clear();
  2.在Query1提交后加入
     TListItem* LI;
     LI=ListView1->Items->Add();
     LI->Caption=Query1BDEDesigner4->Value;
     LI->SubItems->Add(Query1BDEDesigner5->Value)   
     LI->SubItems->Add(IntToStr(Query1BDEDesigner6->Valu))//假如你的数量时整型
     其他的代码自己加吧
     关闭窗体时要delete LI;

#31


请问除了用ListView外,还有别的方法吗?我按你的方法用过listview,不甚理想。请

#32


想一想

#33


请问你是不是用adsl的?

#34


我用的宽带。1M

#35


这样就ok了,我发过程序给你,这个程序做得很好,我上面的这个带grid的form是模仿它的,你看有否办法

#36


如果>1M,请发到xucoh@163.com

#37


发了

#38


hotxu哥,等你答复,有答案望赐教小弟

#39


我还没有收到。

#40


关注。。。

#41


可以按照,主键排序,然后作一个循环,找到主键中没有的数据,作为主键
如果1,2,5,7,则找到3作为主键

#42


3个控件都是同样的datasourse ,你有不给出语句中断,当然会出现你所说的情况啊!

#43


我用DELPHI的,不过DELPHI和BCB很多地方类似 ,不知道能不能帮上你的忙:

如果你的数据库里面的字段没有加上非空约束的话,每次你用ShowModal()都调用Insert(),自然会在在数据库中添加一条记录,只不过该记录的主键是你定义的递增值,而其他字段为空.所以你的FORM显示的时候其他数据控件都是空的.
而你点DBGRID的时候自然是选择了其中一个记录,这样QUERY控件的游标就定义到这个记录上,自然其他与这个QUERY连接的数据控件要显示这条记录了.

另外你如果设置DBGRID的READONLY后,由于调用的是QUERY的INSERT,跟DBGRID一点关系没有,怎么能好使呢??????  DBGRID的READONLY只对在该DBGRID上进行的修改操作有效,对越过DBGRID直接操作QUERY 当然无能为力了,所以要用属性控制只读,也只能控制QUERY 的类似属性,好象叫CanModify吧!

下面进入正题:
BDE用一种称为立即更新(记不清叫什么名字了)的技术,即你一旦对界面上的数据控件(DBEdit,DBGrid等)进行修改,数据马上从本地缓存(实际上就是Query控件)发往数据库进行更新.所以你一调用INSERT()就马上生效.
这一机制有它方便的地方,就是UPDATE的时候几乎不用程序员编写另外的代码;但有不好的地方,即INSERT的时候不方便,以DBGRID为例,当在字段间移动(列方向)时不更新,仅当你移动记录游标时(行方向上的选择)进行更新,这是为了保持同一记录的完整性;但如果要求几条记录同时更新或插入,否则滚回(ROLLBACK)的时候这个就成为了障碍.所以有另外的方法,即动态更新.
动态更新主要用于C/S结构,为减少通信量和其他特殊的控制而使用.当使用这一机制的时候,每当你修改数据,只是修改本地缓存的数据,只有你在程序里显式调用UPDATE方法才把更新反映到数据库中,这样减少了即时更新时每次修改都与SERVER连接的通信量,也叫"需要时更新",当然这要和DELPHI的异常控制和TRY EXCEPT,ROLLBACK一起使用以保证数据库完整性.具体使用控件是UpdateSQL和TDataSet的子类(QUERY等),其中具体的设置见DELPHI帮助,里面还有完整的例子,只不过是英文的,耐心一点就看懂了.这个方法很强大,代价是麻烦一点.所以万不得已当然不用了.

以你的情况来看,根本没必要用,SQLSERVER自己有自增字段的,很好用.1235的问题也不必考虑,主键又没说必须要连续的数字的,为了美观而搞出那么多麻烦事没必要.

以上对DELPHI是肯定的,BCB还要自己去查一下.小弟好长时间没作程序了,具体的名字记得不准确的话大家不要扔柿子啊!

#44


多谢,多谢大哥,多谢前辈指点

#45


说错了,QUERY组件的只读是由RequestLive属性控制的,
TABLE是由READONLY.