博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQL Server 游标运用:鼠标轨迹字符串分割
阅读量:6965 次
发布时间:2019-06-27

本文共 4518 字,大约阅读时间需要 15 分钟。

原文:

一.本文所涉及的内容(Contents)

二.背景(Contexts)

  我们的系统中记录了用户的鼠标行为轨迹字符串,这些字符串的格式是:PosSet:[573,1103,2010-09-03 22:32:35],[864,110,2010-09-03 22:32:57],这个字段表示用户点击页面的X坐标,Y坐标,时间。现在要求对这样字符串进行分割。

  需要注意的是当字符串只有一个坐标的时候,如:PosSet:[513,1303,2010-09-03 22:34:35],你需要考虑这种情况的处理,因为这个时候就没有分隔字符在字符串了。

  还需要考虑字符串不规则的时候的异常处理;

(Figure1:基础数据)

(Figure2:实现效果图)

三.游标模板(Cursor Template)

  在正式解决问题之前我先提供一个游标的模板,它简单的实现了找出数据库中所有的数据库名,其实这个模板的目的是为了提供一个规范化的游标SQL代码模板。

--游标模板DECLARE @databaseName VARCHAR(100)DECLARE @itemCur CURSORSET @itemCur = CURSOR FOR     SELECT name FROM sys.databases         WHERE database_id > 4OPEN @itemCurFETCH NEXT FROM @itemCur INTO @databaseNameWHILE @@FETCH_STATUS=0BEGIN    --逻辑处理    PRINT @databaseName        FETCH NEXT FROM @itemCur INTO @databaseNameEND CLOSE @itemCurDEALLOCATE @itemCur

(Figure3:返回数据库名)

四.鼠标轨迹字符串分割SQL脚本实现(SQL Codes)

(一) 首先创建测试表VisiteLog,并插入测试数据:

--创建测试表[VisiteLog]CREATE TABLE [dbo].[VisiteLog](    [Id] [int] IDENTITY(1,1) NOT NULL,    [PosSet] [varchar](500) NULL, CONSTRAINT [PK_VisiteLog] PRIMARY KEY CLUSTERED (    [Id] ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY]GO--插入测试数据SET IDENTITY_INSERT [dbo].[VisiteLog] ONINSERT [dbo].[VisiteLog] ([Id], [PosSet]) VALUES (1, N'[573,1103,2010-09-03 22:32:35],[864,110,2010-09-03 22:32:57]')INSERT [dbo].[VisiteLog] ([Id], [PosSet]) VALUES (2, N'[513,1303,2010-09-03 22:34:35]')SET IDENTITY_INSERT [dbo].[VisiteLog] OFF--查看数据SELECT * FROM [dbo].[VisiteLog]

(Figure4:基础数据)

 

(二) 接着创建表PosSetInfo,这个表是用来保存鼠标轨迹字符串分割后的数据:

--创建表[PosSetInfo]CREATE TABLE [dbo].[PosSetInfo](    [ID] [int] NULL,    [PosSet_x] [int] NULL,    [PosSet_y] [int] NULL,    [PosTime] [datetime] NULL) ON [PRIMARY]GO

 

(三) 根据鼠标轨迹字符串:[573,1103,2010-09-03 22:32:35],[864,110,2010-09-03 22:32:57]。它坐标点与坐标点之间的分隔符是“,”,X坐标与Y坐标同样适用分隔符“,”,这给我们的分割带来了一些不便,所以我们创建了一个函数,它的作用是把字符串@str以@split分隔符进行分隔,返回第@index次匹配的元素。如下图所示:

-- =============================================-- Author:      
<听风吹雨>
-- Create date: <2010/05/27>-- Description:
<把字符串@str以@split分隔符进行分隔,返回第@index次匹配的元素>
-- =============================================CREATE FUNCTION [dbo].[Get_StrArrayStrOfIndex]( @str VARCHAR(5000), --要分割的字符串 @split VARCHAR(10), --分隔符号 @index INT --取第几个元素)RETURNS VARCHAR(5000)ASBEGIN DECLARE @location INT DECLARE @start INT DECLARE @next INT DECLARE @seed INT SET @str=LTRIM(RTRIM(@str)) SET @start=1 SET @next=1 SET @seed=LEN(@split) SET @location=CHARINDEX(@split,@str) WHILE @location<>0 and @index>@next BEGIN SET @start=@location+@seed SET @location=CHARINDEX(@split,@str,@start) SET @next=@next+1 END IF @location =0 SELECT @location =LEN(@str)+1 RETURN SUBSTRING(@str,@start,@location-@start)END--测试函数SELECT DBO.[Get_StrArrayStrOfIndex]('AB,CDE,FG,HIJK',',',3);

(Figure5:函数测试效果)

 

(四) 下面的SQL脚本就是对VisiteLog表的数据进行分割,再把分割后的字符串保存到PosSetInfo表中,这个脚本的主要做法是先把[573,1103,2010-09-03 22:32:35],[864,110,2010-09-03 22:32:57]以“]”做为分隔符,把数据分割成两段:[573,1103,2010-09-03 22:32:35]和[864,110,2010-09-03 22:32:57],再以“,”做为分割符,找出X坐标、Y坐标和时间;

--鼠标轨迹字符串分割DECLARE @ID int,@PosSet VARCHAR(2000)DECLARE @splitlen INTDECLARE @split NVARCHAR(10)DECLARE @temp VARCHAR(100)DECLARE @PosSet_x INTDECLARE @PosSet_y INTDECLARE @PosTime DATETIMESET @split = ']'DECLARE @itemCur CURSORSET @itemCur = CURSOR FOR     SELECT ID,PosSet FROM [VisiteLog]        WHERE PosSet <> ''OPEN @itemCurFETCH NEXT FROM @itemCur INTO @ID,@PosSetWHILE @@FETCH_STATUS=0BEGIN    SET @splitlen=LEN(@split+'a')-2    WHILE CHARINDEX(@split,@PosSet)>0    BEGIN        SET @Temp = LEFT(@PosSet,CHARINDEX(@split,@PosSet)-1)        SET @Temp = replace(replace(@Temp,',[',''),'[','')        SET @PosSet_x = dbo.Get_StrArrayStrOfIndex(@Temp,',',1)        SET @PosSet_y = dbo.Get_StrArrayStrOfIndex(@Temp,',',2)        SET @PosTime = dbo.Get_StrArrayStrOfIndex(@Temp,',',3)        INSERT PosSetInfo VALUES(@ID,@PosSet_x,@PosSet_y,@PosTime)        SET @PosSet=STUFF(@PosSet,1,CHARINDEX(@split,@PosSet)+@splitlen,'')    END    FETCH NEXT FROM @itemCur INTO @ID,@PosSetEND CLOSE @itemCurDEALLOCATE @itemCur

执行完上面运用游标的SQL脚本,现在查看PosSetInfo表的数据,返回的结果如下图所示:

--查看数据SELECT * FROM [dbo].[PosSetInfo]

(Figure6:分割后数据)

五.补充说明(Addon)

(一) 如果需要循环每个数据库进行操作,你可以使用下面的SQL脚本:

--循环每个数据库EXEC sp_MSForEachDB 'USE [?];SELECT * FROM sys.database_files'

(Figure7:sp_MSForEachDB效果图)

更多sp_MSForEachDB和sp_MSforeachtable的运用,可以参考:

 

(二) 步骤四中处理SQL代码可能性能不是最优的,因为就函数Get_StrArrayStrOfIndex的调用就已经非常频繁的,如果一个PosSet字段的值非常多,你可以考虑用一个表值函数返回一个表。

转载地址:http://irbsl.baihongyu.com/

你可能感兴趣的文章
Cnyunwei-Cacti+Nagios安装说明
查看>>
使用Windows远程桌面(mstsc)通过RDP协议访问Ubuntu/Debian服务器
查看>>
用户第一次登录后要求修改密码
查看>>
Linux内核进程调度的时机和进程切换
查看>>
List使用实例
查看>>
“chaos”的算法---之哈希表(HASH)算法详解
查看>>
学习LINUX的几点注意事项
查看>>
.Net使用SignalR实现消息推送功能预研及Demo
查看>>
基于VMware vSphere 5.0的服务器虚拟化实践(9)
查看>>
2013年下半年信息系统项目管理师考试论文试卷
查看>>
从风投那里得到了了 $100W 的种子期投资且已到账,我该如何组建公司及团队?...
查看>>
每天laravel-20160814| Container -17
查看>>
Squid代理
查看>>
操作系统 地址 概念
查看>>
CentOS 7编译安装php7.0.7以及可能遇到的问题的解决方案
查看>>
html5图片懒加载
查看>>
SpringBatch简介
查看>>
关于CCRANDOM_0_1
查看>>
webworker
查看>>
第二次作业+105032014116
查看>>