2011-04-19 65 views
0

我有一个旧的Delphi系统的问题,此系统插入数据到SQL Server表中。更改表后字段更改

10年后,将表中的一个字段从100变为255个字符长。

系统选择表的所有注册表,并在转换后将它们放在另一个表上。这工作正常。

问题出在系统更新字段的时候。

,显示我的错误

EDBEngineError有消息,因为其他用户更改记录“无法执行编辑。

sConsulta:='SELECT * FROM cuentas WHERE (WALL= 2) AND (SEND_DATE = '01/01/1970')'; 
m_oQryLeg.Close; 
m_oQryLeg.SQL.Clear; 
m_oQryLeg.SQL.Add(sConsulta); 
m_oQryLeg.Open; 
m_oTblNov.Close; 
m_oTblNov.TableName:='des_table'; 
m_oTblNov.Open; 

with m_oTblNov do 
begin 
    while (not m_oQryLeg.EOF) do 
    begin 
    Insert; 
    FieldbyName('COD_HOME').AsString:= m_oQryLeg.FieldByName('USR_HOME').AsString; 
    (...) 
    Post; 

    m_oQryLeg.Edit; 
    m_oQryLeg.FieldByName('SEND_DATE').AsDateTime:= Date; //<-- HERE THE ERROR 
    m_oQryLeg.Post; 

    m_oQryLeg.First; 
    m_oQryLeg.MoveBy(i); 
    inc(i); 
    end;  
end; 
m_oTblNov.Close; 
m_oQryLeg.Close; 

的UpdateMode:upWhereAll

cuentas表:

  • NUM_SOL nvarchar的6 * PK
  • WALL TINYINT 1
  • SEND_DATE SMALLDATETIME 4
  • OBS_CRED nvarchar的255
  • FLCC真正的4
  • STREET为nvarchar 30
+0

您应该提供更多信息,或许是一段代码 – Najem 2011-04-19 15:21:18

+0

您目前使用哪种更新模式?你能提供cuentas表中的列和类型列表吗?有可能其中之一导致错误,BDE有某些浮点类型的问题。 – 2011-04-19 17:15:24

回答

0

这里的问题是,你的目的是试图从数据库中刷新该行,以确保一切都没有改变,更可能的对象截断或圆形的某些价值导致刷新无法返回行。

这可能是由于float值被截断或其他值被关闭引起的。

如果您不/不能更改该列来解决此问题,我会建议更改为upWhereChanged或upWhereKeyOnly。

鉴于日期在大多数Windows数据库中被视为双打,我认为upWhereKeyOnly会是最好的。

编辑:

看你的表之后,它可能与你正在使用一个基于SMALLDATETIME的事实做。 Delphi将所有DateTime数据视为双精度值,并且来回转换可能导致小的舍入问题。

+0

我尝试使用upWhereChanged和upWhereKeyOnly没有任何作品 如果您认为有用,我可以复制所有对象检查器属性。 – JMira 2011-04-19 17:56:05

+0

你可以编写表格吗? – 2011-04-19 18:49:16

1

您正尝试更新您正在使用的查询,同时您正在编辑的表格中,而且这样做不起作用。

既然你知道你要插入查询中的每一行到m_oTblNov,为什么不这样做呢?

sConsultaSELECT :='SELECT * FROM cuentas'; 
sConsultaUPDATE := 'UPDATE cuentas SET Send_Date = :New_Date'; 
// Separate WHERE so you can use it twice. Note the leading space 
// between the first ' and WHERE. 
sWhere := ' WHERE (WALL = 2) and (SEND_DATE = ''01/01/1970'')'; 


m_oQryLeg.Close; 
m_oQryLeg.SQL.Text := sConsulta + sWhere; 
m_oQryLeg.Open; 

m_oTblNov.Close; 
m_oTblNov.TableName:='des_table'; 
m_oTblNov.Open; 

with m_oTblNov do 
begin 
    while (not m_oQryLeg.EOF) do 
    begin 
    Insert; 
    FieldbyName('COD_HOME').AsString:= m_oQryLeg.FieldByName('USR_HOME').AsString; 
    (...) 
    Post; 

    // Don't run these any more. See below. 
    // m_oQryLeg.Edit; 
    // m_oQryLeg.FieldByName('SEND_DATE').AsDateTime:= Date; //<-- HERE THE ERROR 
    // m_oQryLeg.Post; 

    m_oQryLeg.First; 
    m_oQryLeg.MoveBy(i); 
    inc(i); 
    end;  
end; 
m_oTblNov.Close; 
m_oQryLeg.Close; 
m_oQryLeg.SQL.Text := sConsultaUPDATE + sWHERE; 
m_oQryLeg.ParamByName('New_Date').AsDateTime := Date; 
try 
    m_oQryLeg.ExecSQL; 
finally 
    m_oQryLeg.Close; 
end; 
+0

该解决方案的问题是,如果在执行sConsultaUPDATE之前发生某些错误,则系统不会更新日期。 任何方式我解决了这个问题,但不是正确的方式,它应该更新日期字段,像字段一样在工作之前更改表格。 – JMira 2011-04-20 11:42:49

+1

然后,你应该将所有这些包装在一个事务中,并且如果有错误回滚,或者使用两个表和一个过滤器而不是查询和'SELECT'。 – 2011-04-20 23:43:07