简体   繁体   English

在Delphi Xe8中将数据插入数据库

[英]Inserting data into a database in delphi Xe8

The project I am working on requires a Sign Up form that needs to insert the User details into the database table. 我正在处理的项目需要一个“注册”表单,该表单需要将“用户”详细信息插入数据库表中。

The problem is that when the Sign Up Button is clicked the data entered into the edits doesn't save or update into the database. 问题在于,当单击“注册”按钮时,输入到编辑中的数据不会保存或更新到数据库中。 I also get an Access Violation "access violation at 0x0065e3e9 read of address 0x0000006c" , and my code breaks at "tblUsers.Insert" . 我还收到访问冲突“在地址0x0000006c的0x0065e3e9读取时发生访问冲突 ,我的代码在“ tblUsers.Insert”处中断。

I have already tested my code and I have went through each line of code using Breaks to get to the source of the problem and I have found it to be the following portion of code. 我已经测试了我的代码,并且使用Breaks遍历了每一行代码,以找到问题的根源,并且发现它是以下代码部分。

with dmSM do
  begin
    tblUsers.Insert;
    tblUsers['FirstName'] := edtFirstName.Text;
    tblUsers['LastName'] := edtLastName.Text;
    tblUsers['BirthDate'] := cmbDay.Text + ' ' + cmbMonth.Text + ' ' +
                             cmbYear.Text;
    tblUsers['Gender'] := cmbGender.Text;
    tblUsers['AccountName'] := edtAccountName.Text;
    tblUsers['Password'] := edtPassword.Text;
    tblUsers.Post;
end; //end of with

I will try another method but it will be helpful if I can get some help with this. 我将尝试另一种方法,但是如果我可以从中获得一些帮助,它将很有帮助。

Thank you in advance 先感谢您

Dominique 多米尼克

I am putting this answer up for the sake of completeness and for the benefit of future readers. 我提出这个答案是为了完整性,并为将来的读者带来好处。

In your situation, the first thing to do would be to put a breakpoint on btlUsers.Insert. 在您的情况下,第一件事就是在btlUsers.Insert上设置一个断点。 This will confirm that execution reaches that point and the exception occurs when that line executes. 这将确认执行已到达该点,并且在执行该行时会发生异常。

Why the exception? 为什么例外? There is a clue in the part of the message which says "read of address 0x0000006c". 消息的一部分中有一个提示,即“读取地址0x0000006c”。 In Delphi a Nil pointer is effectively 0x00000000, and 6c is a small number (108 in decimal), and that's the clue, the debugger is telling you that the exception occurred a small offset from 0x00000000. 在Delphi中,一个Nil指针实际上是0x00000000,而6c是一个小数字(十进制为108),这就是线索,调试器告诉您异常发生于0x00000000很小的偏移量。

It's a characteristic of compiled Delphi code that the address of a member such as a data field of an object is at some fixed (and usually fairly small, unless the class in question is very large) offset from the base address of the object. Delphi编译代码的一个特点是,成员的地址(例如对象的数据字段)相对于对象的基址有一定的固定偏移量(通常是很小的,除非所涉及的类非常大)。

In you case, the 6c offset is from 0x00000000, so, a plausible explanation is that your code has tried to read a member of an object which is actually Nil. 在您的情况下,6c偏移量从0x00000000开始,因此,一个合理的解释是您的代码已尝试读取实际上为Nil的对象的成员。

So, at the breakpoint, evaluate dmSM and tblUsers. 因此,在断点处评估dmSM和tblUsers。 The debugger tells you that dmSM is Nil and that tblUsers isn't accessible, and it isn't accessible because dmSM is Nil. 调试器告诉您dmSM为Nil,tblUsers无法访问,并且由于dmSM为Nil而无法访问。 Why is dmSM Nil? 为何dmSM Nil?

Most likely because it's a variable that references an object that hasn't been created by the time the breakpoint is reached. 最有可能的原因是,它是一个变量,它引用到断点时尚未创建的对象。 So: 所以:

Go to the Project Manager, right-click your executable in it and select Options. 转到项目管理器,右键单击其中的可执行文件,然后选择选项。 The Forms entry in the tree on the left will tell you which of your forms/datamodules have auto-created variables associated with them and the order in which they are created. 左侧树中的“表单”条目将告诉您哪些表单/数据模块具有与之关联的自动创建的变量以及它们的创建顺序。

Then, look in the .Dpr file. 然后,在.Dpr文件中查找。 It should look much like this: 它看起来应该像这样:

begin
  Application.Initialize;
  Application.CreateForm(TDataModule1, DataModule1);
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

and if it's missing the line that creates the datamodule or it comes after the one that creates the form, that's your problem and it's trivial to fix. 并且如果缺少创建数据模块的行,或者它紧随创建表单的行之后,那是您的问题,而且修复起来很简单。

However, sometimes, everything seems to be ok in the .Dpr file but the exception still occurs. 但是,有时,.Dpr文件中的所有内容似乎都还可以,但是仍然会发生异常。 @JerryDodge raised this point and it's a good one. @JerryDodge提出了这一点,这是一个很好的观点。 What happens is that (usually due to an editing mistake), you duplicate the declaration of one of your auto-created objects. 发生的结果是(通常是由于编辑错误),您复制了一个自动创建的对象的声明。 So now, for instance, you have two dmSMs declared, one in the unit where TdmSM is defined, and the duplicate somewhere else which the compiler sees in the compilation process after the one in your datamodule's unit. 所以,现在,例如,你有定义了两个消失性商源,一个在TdmSM定义的单元,和一个在你的数据模块的单元重复其他地方,编译器看到在编译过程中。 And because it's seen the duplicate more recently when it compiles the unit where the exception occurs, it assumes that your code is referring to the duplicate, not the original. 并且由于在编译发生异常的单元时最近才看到重复项,因此假定您的代码引用的是重复项,而不是原始的。

The reason I've tried to answer this q in such grinding detail is to make the point that a lot of the debugging process is thinking through the clues you get from carefully observing (and reporting, in an SO q) the behaviour of your errant program. 我试图以如此细腻的细节回答这个问题的原因是为了指出,许多调试过程正在思考通过仔细观察(并以SO q形式报告)错误行为所获得的线索。程序。

Finally, avoid using "with". 最后,避免使用“ with”。 Although it may save you a bit of typing, in the long run it tends to cause more trouble than it's worth. 尽管它可以为您节省一些打字时间,但从长远来看,它往往会带来更多的麻烦,而不是值得的。 In your form unit, if you need to have to keep referring to some object in the datamodule, either assign its value to a variable scoped locally to the procedure in the form where you're doing it, or (better) define a function which returns the object in question, like so 在表单单元中,如果需要继续引用数据模块中的某个对象,则可以将其值分配给在您执行表单的过程中局部作用于过程的局部变量,或者(更好)定义一个函数来返回有问题的对象,像这样

function TForm1.tblUsers : TDataSet;
begin
  Result := dmSM.tblUsers;
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM