我一直使用这样的脚本将数据插入到delphi 7中的表中
sql := 'INSERT INTO table_foo (field1,field2,field3) VALUES ('
+quotedstr('value1')
+','+quotedstr('value2')
+','+quotedstr('value3')
+')';
adoquery1.close;
adoquery1.sql.text := sql;
adoquery1.execsql;
但我的一位朋友向我展示了另一种看起来更干净的方式,如下:
sql := 'SELECT * FROM table_foo';
adoquery1.close;
adoquery1.sql.text := sql;
adoquery1.open;
adoquery1.insert;
adoquery1.fieldbyname('field1').asstring := quotedstr('value1');
adoquery1.fieldbyname('field2').asstring := quotedstr('value2');
adoquery1.fieldbyname('field3').asstring := quotedstr('value3');
adoquery1.post;
两种方法中的哪一种更好(更快,更容易阅读/调试)?特别是当table_foo
中的数据很大或者还有更多字段要填充时。
答案 0 :(得分:9)
如果使用INSERT INTO
语句,请使用参数(出于可读性的原因,避免SQL注入,SQL缓存),例如:
adoquery1.sql.text := 'INSERT INTO table_foo (field1, field2) values (:field1, :field2)';
adoquery1.Parameters.ParamByName('field1').Value := value1;
adoquery1.Parameters.ParamByName('field2').Value := value2;
我更喜欢第二种方式(我会解释一下小调整)。 由于您要插入一条记录,因此调整是选择空记录集,即:
SELECT * FROM table_foo where 1=0
这样您就不会从表中选择所有记录。
在分配值时也不需要使用QuotedStr
,即:
adoquery1.FieldByName('field1').AsString := 'value1';
我使用此方法的主要原因是它易于阅读和维护。
我不需要用纯SQL查询来打扰自己。我不需要处理指定参数数据类型所需的参数(例如Parameters.ParamByName('field1').DataType := ftInteger
)。无需ParseSQL
。
我只是使用DataSet As(Type)
,例如
FieldByName('field1').AsBoolean := True;
如果我需要在单个事务中插入多个记录,我也更喜欢使用此方法。
第二种方法的缺点是通过SELECT FROM
短暂访问SQL服务器。
另一个选择是创建一个SQL存储过程,将值传递给SP,并在SP中写入所有SQL逻辑。
答案 1 :(得分:1)
第二种方法需要来自数据集的更多本地资源,因为它将保留原始结果集的内存,然后使用该内存来决定应使用哪个SQL语句将哪些记录发送到服务器。该方法还需要与服务器的实时连接以及数据集中的双向本地游标集。 TADODataset
为你完成所有这些。它对你的工作更少有效,但它会从系统中消耗更多。在我看来,决定取决于哪个资源更重要,你的时间或计算机资源。
Personaly,我更喜欢使用TClientDataset
(CDS)。它将允许您拥有内存中的数据集,并通过在相应的TDatasetProvider.BeforeUpdateRecord
中使用TDatasetProvider
事件,您将获得两全其美:绝对控制将哪个句子提交给服务器,以及灵活的双向数据集,在GUI上运行良好。
此外(这对我来说是最重要的),使用CDS,您将能够将DBMS的细节与应用程序的主逻辑隔离开来,因为该逻辑将在独立于数据库的数据集上运行。如果你必须从ADO转移到DBX,那么你的主代码不会受到伤害,因为它是用CDS写的。