Ang*_*ge1 2 sql-server stored-procedures
我有一个程序如下:
create procedure MoveDailyData
@date1 bigint
as
declare @datenow bigint
set @datenow = datediff(S,'01/01/1970',getdate())
if ((@datenow)-@date1)>=86400
begin
insert into FinalLogs(problem,channel_number,username,app_id,Is_On,logtype,viewing_channel,playtime,macaddress,wifimacaddress,seen,version,date)
select problem,channel_number,username,app_id,Is_On,logtype,viewing_channel,playtime,macaddress, wifimacaddress,seen,version,date from DayTempTable
delete from DayTempTable where (@datenow-@date1)>=86400
end
else select 'Not Yet';
Run Code Online (Sandbox Code Playgroud)
该过程应将数据从 1 个临时表复制到最后一个(按每日计划),然后从临时表中删除该数据。相反,我注意到每隔几天,数据不会被复制,而只是从临时表中删除,因此我丢失了大量相关数据。该date列是一个bigint(日期另存为unix time)。在这个过程中我做错了什么吗?
这里有几个问题:
没有显式的 BEGIN TRAN/COMMIT/ROLLBACK 周围,INSERT并将DELETE它们分组为一个原子操作。
没有 TRY / CATCH 结构来管理COMMITvs ROLLBACK.
为什么要使用 UNIX 时间而不是实际DATETIME值?
为什么没有WHERE条件SELECT喂食INSERT?
但与所述问题最直接相关的是:整个DayTempTable表被删除,因为语句的WHERE条件DELETE是一个简单的布尔表达式并且不引用该表的任何字段。意思是,如果(@datenow-@date1)>=86400计算结果为true,则所有行都将被删除。否则,不会删除任何行。如果要删除行的子集,则需要实际过滤表 ;-)。
显式事务中INSERTthen的另一种方法DELETE是通过OUTPUT子句同时处理两个操作:
DELETE tbl
FROM DayTempTable tbl
OUTPUT DELETED.problem, DELETED.channel_number, DELETED.username, DELETED.app_id,
DELETED.Is_On, DELETED.logtype, DELETED.viewing_channel, DELETED.playtime,
DELETED.macaddress, DELETED.wifimacaddress, DELETED.seen, DELETED.version,
DELETED.date
INTO FinalLogs (problem, channel_number, username, app_id, Is_On, logtype,
viewing_channel, playtime, macaddress, wifimacaddress, seen,
version, date)
WHERE (@datenow - tbl.[date_field]) >= 86400;
Run Code Online (Sandbox Code Playgroud)
然后您不需要显式事务(即 BEGIN TRAN / COMMIT / ROLLBACK),因为它是自动处理的。但是您仍然应该进行尝试/捕捉。
更好的是将WHERE条件更改为一个简单的、可讨论的表达式:
WHERE tbl.[date_field] <= (@datenow - 86400);
Run Code Online (Sandbox Code Playgroud)此外,我不会使用术语“临时表”来指代该DayTempTable表,因为它实际上不是一个临时表(用单井号或双井号#作为前导字符表示)表名)。
| 归档时间: |
|
| 查看次数: |
129 次 |
| 最近记录: |