• 用触发器删除txt中指定条件内容行数据


    一: 删除txt中指定条件内容行数据

    下面图中TXT的文档内容是原始数据,现在我需要删除A0126开头的行内容,保留delete,insert,update开头的代码行数据.

    因为从服务器上拷出来的日志代码有自动换行的,就是可能一条insert语句在txt中会有好几行.

    比如图中的第5行delete代码涉及到下一行(就是5,6行都是delete的代码.)

    所以针对这样的情况,第6行数据还是要保存的.

    像A0126开头的代码,如图中(2,3,4行)都是要剔除的.

    一开始没想到用什么方法好,只有手动删除,删的我眼冒泪光啊.而且不小心还可能删错了!

    晚上下班回去后想了想,终于想出个雏形了.今天上班试了下,感觉还可以,就是过程有点繁杂.

    但相对一行一行的手动删除(特别是针对上万行的数据量),这个效果还是很明显嘀.

    【思路】先把txt数据复制到excel中,然后导入到sql server 2008中(我试过txt直接导入,但是会报错。

     所以我就把它复制到excel中再导入了。)

               导入成功后,写个游标(下面给出具体内容)获取要剔除的行数,然后删除要剔除的行数。

               最后select出结果集。

    【具体步骤】:

    1: 把txt内容复制到excel 2007中。 excel的设计如下图(特别要注意的是,第一行最好加个字段名称。)

          A列的ID自己加的,为了标识在txt中的行数。为后面做准备。

    2: 把EXCEL数据导入到Sql Server 2008 中(具体方法在此省略,百度之或者参考:http://www.cnblogs.com/ycusking/archive/2011/11/28/excel_sqlserver.html  )

     成功导入数据库:(导入数据库新建的表名为'out5') 下图为'sp_help out5'的信息:

    3: 最关键的一步:写游标,把要删除的内容的行数(也就是表中的id号)插入到'out_id5'表中,最后只要select出out5

    中的id不在out_id5表中的数据即可:

     ' select note from out5 where id not in (select id from out_id5)  order by id '

     1 --定义游标
    2 declare cursor_del5 cursor for --游标名称为:cursor_del5
    3 select id,substring(note,1,5) from out5 order by id
    4
    5
    6 --打开游标
    7 open cursor_del5
    8
    9 declare @id int
    10 declare @str char(5)
    11
    12
    13 --读取游标中的第一条数据
    14 fetch next from cursor_del5 into @id,@str
    15
    16 --判断是否从游标中读取数据
    17 while (@@FETCH_STATUS = 0)
    18 begin
    19 if @str = 'A0126' --需要删除的是以'A0126'开头的一行或多行数据
    20 begin
    21 if not exists (select 1 from out_id5 where id = @id )
    22 begin
    23 ---插入第一笔'A0126开头的id
    24 insert into out_id5(id,str5) select @id,@str
    25 end
    26
    27 declare @mid int --out5中最大的id号
    28 select @mid = max(id) from out5
    29
    30
    31 --获取下一行的开头字母,如果下一行为空,则自动填字符串'kong'
    32 select @id = @id + 1
    33 select @str = isnull(substring(note,1,5),'kong') from out5 where id = @id
    34
    35
    36 --如果下一行不是'delet','inser'或'updat'开头的,也要删除此行的数据(即把此行id插入out_id5表中)
    37 while @str not in ('delet','inser','updat')
    38 begin
    39 if not exists (select 1 from out_id5 where id = @id )
    40 begin
    41 insert into out_id5(id,str5) select @id,@str
    42 end
    43
    44 --如果@id小于最大id值,继续查找下一行的数据
    45 if @id <= @mid
    46 begin
    47 select @id = @id + 1
    48 select @str = isnull(substring(note,1,5),'kong') from out5 where id = @id
    49 end
    50 else
    51 select @id = @mid +1 , @str = 'delet' --为了退出while语句
    52 end
    53 end
    54
    55
    56 fetch next from cursor_del5 into @id, @str
    57
    58
    59 end
    60
    61 --关闭游标
    62 close cursor_del5
    63
    64 --删除游标
    65 deallocate cursor_del5
    66
    67
    68

    执行这游标之前,需要先建个表:

    create table out_id5(

    id int,

    str5 char(5) ---为了便于对比out5表的数据

    )

    建完表后,再在SSMS上执行上图中的游标代码就可以了!

    成功执行完后,再执行下面的sql语句:

    select id,note into out_result5 from out5 where id not in (select id from out_id5) order by id

    然后select出out_result5表中的note字段,复制到txt中,就是剔除后的结果集:

    这个结果集看起来还是基本符合要求的!

    但是这结果集还不是最终想要的,凡是涉及到对repair_histoty,kuandai_pretreat_history这两张表进行

    update,insert,delete等操作的,通通地删除,一个不留!那怎么办呢? 其实还可以继续用游标:

    二: 删除指定表的操作的内容行:

    在执行游标之前,还是要准备一张表del_id5 ,这张表存放的是刚刚获取的结果表out_result5中对repair_history,kuandai_pretreat_history两张表操作的的数据行数:

    create table del_id5(
    id int,
    str5 char(5)
    )

    下面是游标的代码:

     1 --定义游标
    2 declare cursor_del1 cursor for
    3 select id,substring(ltrim(substring(note,1,100)),1,5) from out_result5 order by id
    4
    5
    6 --打开游标
    7 open cursor_del1
    8
    9 declare @id int
    10 declare @str char(5)
    11
    12 --读取游标中的第一条数据
    13 fetch next from cursor_del1 into @id,@str
    14
    15 --判断是否从游标中读取数据
    16 while (@@FETCH_STATUS = 0)
    17 begin
    18 if @str in('inser','delet','updat')
    19 begin
    20 declare @dnote varchar(100)
    21 select @dnote = ltrim(substring(note,1,100)) from out_result5 where id = @id
    22
    23 --txt中,操作的表名都有一个规律,就是在upd,ins或del后面且表名前都有'dbo.'字符串
    24 --我们只要根据'dbo.'来截取后面的表名,就可以判断是否要剔除此行数据了
    25 if ( substring(@dnote,charindex('dbo.',@dnote)+4,14) = 'repair_history' or
    26 substring(@dnote,charindex('dbo.',@dnote)+4,24) = 'kuandai_pretreat_history')
    27 begin
    28 if not exists (select 1 from del_id5 where id = @id )
    29 begin
    30 insert into del_id5(id,str5) select @id,@str
    31 end
    32
    33
    34 declare @mid int
    35 select @mid = max(id) from out_result5
    36 select @id = MIN(id) from out_result5 where id > @id --获取下一行id
    37
    38 if @id <= @mid
    39 begin
    40 select @str =substring(ltrim(substring(note,1,100)),1,5) from out_result5 where id = @id --获取下一行的代码内容
    41
    42 --如果不是'delet','inser'或'updat'开头,则还要继续剔除此行数据
    43 while @str not in ('delet','inser','updat')
    44 begin
    45
    46 if not exists (select 1 from del_id5 where id = @id )
    47 begin
    48 insert into del_id5(id,str5) select @id,@str
    49 end
    50
    51 select @id = MIN(id) from out_result5 where id > @id --获取下下行id
    52
    53 if @id <= @mid
    54 begin
    55 --获取下下行代码开头的字符串,返回给while继续进行判断
    56 select @str = substring(ltrim(substring(note,1,100)),1,5) from out_result5 where id = @id
    57 end
    58 else begin
    59 select @id = @mid +1 , @str = 'delet' --标识退出while
    60 end
    61 end --end of while @srt ...
    62 end --end of if @id <= @mid
    63 end
    64 end --end of if @str in('inser','delet','updat')
    65
    66
    67 fetch next from cursor_del1 into @id, @str
    68
    69
    70 end
    71
    72
    73
    74 --关闭游标
    75 close cursor_del1
    76
    77 --删除游标
    78 deallocate cursor_del1
    79
    80
    81

    成功执行完游标后,下面就可以获取结果集了:

    select note from out_result5 where id not in (select id from del_id5) order by id

    copy到txt中,效果如下图:

    P.S: 如果txt文档的第一行数据不是以'update','insert','delete'开头,也不是以'A0126'开头的,那么最后的

    结果集中还是会保留这一行的数据的.所以如果有此情况的话,得手动删除前面几行数据!

    最后,这样看起来好像还可以,获取到了最终想要的结果集体.

    但是,这还不是最佳效果,因为换行的缘故(并不是txt中自动换行),导致其中的一句insert,update或delete语句

    被拆分成了2行甚至更多的行数.

    那有什么办法能够合并几行的数据呢? 前面两个习惯了用游标,所以我首先想的是能否继续用游标来拼接内容呢?

    三: 拼接txt中几行条件数据到一行中.

     1 --定义游标
    2 declare cursor_del1 cursor for
    3 select id,substring(ltrim(substring(note,1,100)),1,5) from out_result10 order by id
    4
    5
    6 --打开游标
    7 open cursor_del1
    8
    9 declare @id int
    10 declare @str char(5)
    11
    12 --读取游标中的第一条数据
    13 fetch next from cursor_del1 into @id,@str
    14
    15 --判断是否从游标中读取数据
    16 while (@@FETCH_STATUS = 0)
    17 begin
    18 if @str in('inser','delet','updat')
    19 begin
    20
    21 declare @maxid int
    22 declare @dnote varchar(100)
    23 declare @textid int, @text varchar(2000)
    24
    25 select @textid = @id
    26 select @text = rtrim(note) from pingjie10 where id = @id
    27
    28
    29 select @maxid = MAX(id) from pingjie10
    30 select @id = isnull(MIN(id),0) from pingjie1 where id > @id
    31
    32 if @id < @maxid and @id != 0 --下一个id小于最大值且不为0
    33 begin
    34 select @dnote = substring(ltrim(substring(note,1,100)),1,5) from out_result10 where id = @id
    35
    36 while @dnote not in ('delet','inser','updat')
    37 begin
    38 select @text = @text+LTRIM(rtrim(note)) from pingjie10 where id = @id --拼接前两条
    39
    40 select @id = @id +1
    41
    42 if @id < @maxid and @id != 0
    43 begin
    44 select @dnote = substring(ltrim(substring(note,1,100)),1,5) from out_result10 where id = @id
    45 select @id = @id + 1
    46 end
    47 else begin
    48 select @dnote = 'delet' --标识退出while循环
    49 end
    50 end
    51
    52 end
    53
    54 insert into pj_result10(id,note) select @textid,@text
    55
    56 end
    57
    58 fetch next from cursor_del1 into @id, @str
    59
    60
    61 end
    62
    63
    64
    65
    66 --关闭游标
    67 close cursor_del1
    68
    69 --删除游标
    70 deallocate cursor_del1
    71
    72
    73

    结果如下:

    第三步的拼接txt中几行条件数据到一行中,好像只能拼接2行,3行的不清楚怎么不会出来.

    难道是while语句有问题?这个以后有时间再回来修改修改...

  • 相关阅读:
    Linux下chkconfig命令详解
    几种主流的快照技术
    HANA内存数据库与oracle数据库的性能比较
    计算机网络知识汇总
    bzoj1211: [HNOI2004]树的计数 prufer序列裸题
    1003: [ZJOI2006]物流运输 最短路+dp
    HDU
    2243: [SDOI2011]染色 树链剖分+线段树染色
    bzoj1036: [ZJOI2008]树的统计Count 树链剖分
    bzoj1042: [HAOI2008]硬币购物 dp+容斥
  • 原文地址:https://www.cnblogs.com/ycusking/p/cursor.html
Copyright © 2020-2023  润新知