我自己写段代码function getdata(p:pointer):boolean;stdcall; var str:string; id:integer; Begin Coinitialize(nil); EnterCriticalSection(cs); form1.ADOQuery1.Close; form1.ADOQuery1.SQL.Clear; form1.ADOQuery1.SQL.Add('select count(1) from overtime1') ; form1.ADOQuery1.Open; if form1.ADOQuery1.RecordCount=0 Then id:=0 else id:=form1.ADOQuery1.Fields[0].AsInteger; str:='INSERT INTO overtime1(number,person_number,kind,id) SELECT number,person_number,kind,id FROM overtime WHERE id ' + ' > '+inttostr(id)+' and id < '+inttostr(id+11)+' ORDER BY id '; form1.ADOQuery1.Close; form1.ADOQuery1.SQL.Clear; form1.ADOQuery1.SQL.Add(str); form1.ADOQuery1.ExecSQL; LeaveCriticalSection(cs); end;procedure TForm1.Timer1Timer(Sender: TObject); var wd:Dword; begin Createthread(nil,0,@getdata,nil,0,wd); end; 我哪怕把timer的间隔设为 100 ,结果都很正常。我不知公司的代码不行????
timer事件中执行insert不行吗?为什么还要使用线程?oracel数据库中有好多重复的数据,则是另一个问题了
想删除,还是想不让它再产生?这就需要很具体的信息了
我感觉我在 timer和线程处理不好, 当线程还没有完成插入时,有可以 timer再触发一次,这样有可能插入重复数据了。不知怎么处理这两者的关系?
我感觉我在 timer和线程处理不好, 当线程还没有完成插入时,有可能 timer再触发一次,这样有可能插入重复数据了。不知怎么处理这两者的关系?上面打错字了
不用定时器
var
str:string;
id:integer;
Begin Coinitialize(nil);
EnterCriticalSection(cs);
form1.ADOQuery1.Close;
form1.ADOQuery1.SQL.Clear;
form1.ADOQuery1.SQL.Add('select count(1) from overtime1') ;
form1.ADOQuery1.Open;
if form1.ADOQuery1.RecordCount=0 Then
id:=0
else
id:=form1.ADOQuery1.Fields[0].AsInteger; str:='INSERT INTO overtime1(number,person_number,kind,id) SELECT number,person_number,kind,id FROM overtime WHERE id ' +
' > '+inttostr(id)+' and id < '+inttostr(id+11)+' ORDER BY id ';
form1.ADOQuery1.Close;
form1.ADOQuery1.SQL.Clear;
form1.ADOQuery1.SQL.Add(str);
form1.ADOQuery1.ExecSQL;
LeaveCriticalSection(cs);
end;procedure TForm1.Timer1Timer(Sender: TObject);
var
wd:Dword;
begin
Createthread(nil,0,@getdata,nil,0,wd);
end;
我哪怕把timer的间隔设为 100 ,结果都很正常。我不知公司的代码不行????
因为oracel和mssql有点不一样,orcacle插入后一定要 commit.但现在我也不能确定是什么引起重复数据。
改为单线程自行循环插,应该没问题了另外,靠count(1)作为后面id的依据,好像不大可靠:万一中间删掉过记录。
应该以max(id)作为后面id的依据才对
我的本意是 先把 timer禁用,再执行线程,等线程执行完,再把timer启用。但这样比较难控制,不知sz_haitao有什么好的办法
数据是否重复,那是插入数据代码没处理好,除非有并发的情况,否则和线程没关系
当然中间SLEEP(10000)
可以这样.在线程执行完毕时,向主窗口发送一个消息,设置一个变量,TIMER里面每都检查这个变量.余下的我就不说了吧.
lpTimerAttributes: PSecurityAttributes; {安全}
bManualReset: BOOL; {True: 可调度多个线程; False: 只调度一个线程}
lpTimerName: PWideChar {名称}
): THandle; stdcall; {返回句柄}function SetWaitableTimer(
hTimer: THandle; {句柄}
var lpDueTime: TLargeInteger; {起始时间}
lPeriod: Longint; {间隔时间}
pfnCompletionRoutine: TFNTimerAPCRoutine;{回调函数的指针}
lpArgToCompletionRoutine: Pointer; {给回调函数的参数}
fResume: BOOL {是否唤醒系统}
): BOOL; stdcall; {}
如果还有重复,那就是sql的逻辑问题了
Timer.Enable := false; //关闭定时器
width Thread.Create do
OnTerminate := CloseSyncThread; //注意此处,CloseSyncTherad是线程执行完毕释放时的事件。定义如下:
procedure CloseSyncThread(Sender:TObject);
begin
Timer.Enable := true; //启动定时器
end;在线程里加入FreeOnTerminate:=true; //线程结束时,自动释放资源
这就是一个完整的循环了!
其实线程和timer没有多少影响,timer可以控制好线程。数据重复是因为oracle表结构有问题,它只存了
yyyy-mm-dd hh:nn:ss 并没有保存毫秒。所以我把这字段改 timestamp就可以了。