我有两个相同的表(列数,名称和设置)。每个表上有相同的一行,相同的信息。其中一列是BLOB
类型的列,包含一个Image (bmp)。
两个行/表都有一个id
列auto increment
,所以两个表中每一行的id都是相同的。设置为blob
类型的列可以是NULL
(它已设置)。
我使用的action
有以下查询的:
dbmodule.arhivaQuery.SQL.Clear;
dbmodule.arhivaQuery.SQL.Add('UPDATE `database_name`.`2nd_table_name` SET `column_name`=deleted WHERE `id`=''' + inttostr(dbmodule.comenziDataSetid.Value) + ''';');
dbmodule.arhivaQuery.ExecSql(true);
理论上,这应该通过从blob列中删除bmp来更新第二个表中的行,或者更确切地说,将bmp替换为单词"deleted"。如果没有,图像仍然在列/行中。
有几点需要澄清:
dbmodule是包含数据集、数据源、SQL连接和查询的数据模块的名称。(TSimpleDataSet
, TDataSource
, TSQLConnection
, TSQLQuery
).
arhivaQuery是我正在使用的查询的名称(一个TSQLQuery
)column_name =列的名称,我在这个粘贴中进行了编辑,以便您可以获得更清晰的图像。
您注意到,在最后,我使用第一个表中的行id来更改第二个表中的数据,这就是为什么会出现这种情况(两个表中行id相同)。
当我执行此操作时,它应该在两个表中保留两个行,但通过从blob列中删除其图像来更新第二个表中的行。因此,在此之后,我应该有row
在第一个table
与blob列中的图像和相同的行在第二个表中,在blob列中没有图像。
我猜我的sql语法是错误的(有一些警告这么说),有人能帮我纠正吗?
如果要清除blob字段的内容,请将其赋值为NULL。
dbmodule.arhivaQuery.SQL.Add('UPDATE `database_name`.`2nd_table_name` SET `column_name` = NULL WHERE `id`=''' + inttostr(dbmodule.comenziDataSetid.Value) + ''';');
如果你想显示那些没有值的列的删除的,在使用IFNULL()
或COALESCE()
检索内容时,在SELECT
语句中这样做,无论你的DBMS支持哪个。
您可以做的另一个改进(为了简化编码和防止SQL注入)是停止连接SQL并切换到使用参数。这也意味着你可以停止所有的'''
双/三/四引号和数据类型转换的废话,因为DB驱动程序会为你照顾所有的。
dbmodule.arhivaQuery.SQL.Add('UPDATE `database_name`.`2nd_table_name` SET `column_name` = NULL WHERE `id`= :ID;');
// Use AsInteger, AsString, AsFloat, or AsBoolean, whichever fits your
// column data type. Notice no quotes, no call to IntToStr or FloatToStr.
dbmodule.arhivaQuery.ParamByName('ID').AsString := dbmodule.comenziDataSetid.Value;
注意:一些DB驱动程序将需要Params.ParamByName
代替。如果一个不工作,另一个会。
最后,将长行SQL代码分成可管理的部分,这样您就可以停止所有的滚动来阅读它。
dbmodule.arhivaQuery.SQL.Add('UPDATE `database_name`.`2nd_table_name`');
dbmodule.arhivaQuery.SQL.Add('SET `column_name` = NULL WHERE `id`= :ID;');
dbmodule.arhivaQuery.ParamByName('ID').AsString := dbmodule.comenziDataSetid.Value;