我知道这个问题可能是在我无法设法让我的事情发生之前被问到的。我设置我的SQL有两个表,但在这个例子中,我将只使用一个名为“Book'”的表。它有各种各样的列,但我想要使用的列称为' WR','客户','联系人'模型', ' SN','状态','技术'' WDone'和' IN'。
我想在名为edtWR
的编辑框中输入文字,我希望按钮btnSearch
能够搜索' WR'列,直到它匹配(所有条目将不同)。一旦有了它,它必须写“客户”,“联系人”,“模型”,“SN'”,“状态”和#39 ;对于标签,我们称之为lblCustomer
lblContact
lblModel
lblSN
& lblStatus
。
一旦此人确认这是' WR'他们希望必须将文本输入编辑框和一个名为edtTech
,mmoWDone
和edtIN
的备忘录,然后点击btnUpdate
。然后应该更新该记录。
我在被叫dtbOut
上有3个ADO连接,这是我的ADOConnection1,tableOut
表示我的ADOTable,而dataOut
表示ADODataSet。如果有帮助,dataOut的命令文本为Select * From Book
。
我可以让整个过程在访问数据库上完美运行,但几乎没有SQL经验,我需要帮助。我将为Access数据库添加代码,以备需要参考时使用。
procedure TFOut.btnSearchClick(Sender: TObject);
begin
dataout.Filter := 'WR = ''' + 'WR ' + edtwr.Text + '''';
dataout.Filtered := True;
dataout.First;
lblcustomer.Caption := 'Customer: ' + dataout.FieldByName('Customer').AsString;
lblcontact.Caption := 'Contact: ' + dataout.FieldByName('Contact').AsString;
lblSN.Caption := 'SN: ' + dataout.FieldByName('SN').AsString;
lblModel.Caption := 'Model: ' + dataout.FieldByName('Model').AsString;
lblstatus.Caption := 'Status: ' + dataout.FieldByName('Status').AsString;
procedure TFOut.btnUpdateClick(Sender: TObject);
begin
dataout.Edit;
dataout.FieldByName('Tech').AsString := edtTech.Text;
dataout.FieldByName('WDone').AsString := mmoWDone.Lines.GetText;
dataout.FieldByName('IN').AsString := edtIN.Text;
dataout.Post;
end
我是否需要在表单上添加任何其他组件才能在SQL中执行此操作,我需要什么以及如何启动。我已经阅读了很多东西,似乎我需要获得一个ADOQuery1
但是当涉及到ADOQuery1.SQL
部分时,我会从马车上掉下来。我也尝试了Access方式,我可以搜索但是一旦我尝试更新,我得到一个"不足的关键列信息,用于更新或刷新"错误,女巫我也不知道如何解决。
如果我需要另外说明问题,请解释如何更改以使其更清楚,如果我需要在整个说明或代码中添加任何内容,请告知我什么。
答案 0 :(得分:0)
SO实际上不是数据库教程的地方,所以我不打算这样做 尝试一个,而是专注于一个基本的事情,在你开始之前理解和正确进入你的数据库设计是至关重要的 编写Delphi数据库应用程序。 (我将谈谈这个问题 Sql Server,而不是MS Access。)
您提到收到错误“用于更新或刷新的关键列信息不足”,您说您不知道该如何处理。
Delphi数据集(任何类型,不仅仅是ADO数据集)通过维护一个逻辑光标来操作,该光标指向数据集中的一行。当您打开(非空)数据集时,此光标指向数据集中的第一行,您可以使用各种TDataSet方法移动光标,例如Next
& Prior
,First
,Last
和MoveBy
。一些(但不是全部)类型的TDataSet实现了它的Locate
方法,使您可以转到与您指定的条件匹配的行,而不是其他类型。 Delphi的ADO组件做实现Locate
(btw,Locate
对您已从服务器检索的行进行操作,而不是在服务器上查找行> EM>)。
面向Sql的TDataSets(如TAdoQuery)的一个关键思想是,您可以让它自动生成Sql语句来执行更新,删除和插入。这不仅是一项重要的生产力帮助,而且当您尝试自己完成时,它可以避免编码错误和遗漏。
如果您观察ADO使用SS的Profiler实用程序对MS Sql Server表执行其操作,那么使用设计良好的数据库,您会发现它可以非常有效地执行此操作提供数据库设计遵循一个基本规则,即必须有一种方法来唯一地标识表中的特定行。最常见的方法是在每个表中包含一个int(eger)ID列,通常作为第一列,并将其定义为表的“主键”。虽然还有其他方法可以在此列中生成合适的ID值,但Sql Server具有特定的列类型“Identity”,它在服务器上处理此问题。
一旦表格有这样一个列,ADO层(由Windows提供的数据集组件,如TAdoQuery所在的数据访问层)可以自动生成Sql语句来进行更新和删除,例如
Delete from Table1 where Table1ID = 999
和
Update Table1 set SomeCharField = 'SomeValue' where Table1ID = 666
您可以将其留给AdoQuery来从服务器中获取新插入的行的ID值。
让Sql自动生成的一个有用方面是它确保Sql只影响单行,因此避免影响比你想要的更多的行。
一旦你的数据库设计的这个关键方面正确,你会发现Delphi的TDataSet后代,如TAdoQuery及其支持DB的组件,可以处理大多数简单的数据库应用程序,而无需编写任何Sql语句所有要更新,插入或删除 行。但是,通常,您仍然需要编写Sql语句,以便通过使用“Where”子句将检索到的行限制为服务器上行的子集来从服务器检索所需的行。
也许你的下一步应该是阅读参数化的Sql查询,以减少你对“Sql Injection”的曝光:
https://en.wikipedia.org/wiki/SQL_injection
因为最好养成使用参数编写Sql查询的习惯。顺便说一句,Sql Injection不仅仅是关于Sql在通过互联网发送时被拦截和修改:有一些注入形式,一个知道他们正在做什么的恶意用户可以简单地输入一些额外的Sql语句,其中应用程序“期望“他们只是指定一些列值作为搜索标准。