SQL Server 游标运用:鼠标轨迹字符串分割
一.本文所涉及的内容(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 CURSOR
SET @itemCur = CURSOR FOR
SELECT name FROM sys.databases
WHERE database_id > 4 OPEN @itemCur
FETCH NEXT FROM @itemCur INTO @databaseName
WHILE @@FETCH_STATUS=0
BEGIN
--逻辑处理
PRINT @databaseName FETCH NEXT FROM @itemCur INTO @databaseName
END CLOSE @itemCur
DEALLOCATE @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] ON
INSERT [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)
AS
BEGIN
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 INT
DECLARE @split NVARCHAR(10)
DECLARE @temp VARCHAR(100)
DECLARE @PosSet_x INT
DECLARE @PosSet_y INT
DECLARE @PosTime DATETIME
SET @split = ']'
DECLARE @itemCur CURSOR
SET @itemCur = CURSOR FOR
SELECT ID,PosSet FROM [VisiteLog]
WHERE PosSet <> '' OPEN @itemCur
FETCH NEXT FROM @itemCur INTO @ID,@PosSet
WHILE @@FETCH_STATUS=0
BEGIN
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,@PosSet
END CLOSE @itemCur
DEALLOCATE @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 Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database)
SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database)
(二) 步骤四中处理SQL代码可能性能不是最优的,因为就函数Get_StrArrayStrOfIndex的调用就已经非常频繁的,如果一个PosSet字段的值非常多,你可以考虑用一个表值函数返回一个表。
SQL Server 游标运用:鼠标轨迹字符串分割的更多相关文章
- SQL Server游标 C# DataTable.Select() 筛选数据 什么是SQL游标? SQL Server数据类型转换方法 LinQ是什么? SQL Server 分页方法汇总
SQL Server游标 转载自:http://www.cnblogs.com/knowledgesea/p/3699851.html. 什么是游标 结果集,结果集就是select查询之后返回的所 ...
- SQL Server日期时间格式转换字符串详解 (详询请加qq:2085920154)
在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...
- SQL Server日期时间格式转换字符串
在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...
- SQL Server日期时间格式转换字符串详解
本文我们主要介绍了SQL Server日期时间格式转换字符串的相关知识,并给出了大量实例对其各个参数进行对比说明,希望能够对您有所帮助. 在SQL Server数据库中,SQL Server日期时间格 ...
- SQL点滴3—一个简单的字符串分割函数
原文:SQL点滴3-一个简单的字符串分割函数 偶然在电脑里看到以前保存的这个函数,是将一个单独字符串切分成一组字符串,这里分隔符是英文逗号“,” 遇到其他情况只要稍加修改就好了 CREATE FUN ...
- sql server 游标的简单用法
sql server游标: --定义游标 declare cursor1 cursor for select ID,Name from A --打开游标 open cursor1 declare @i ...
- 使用IP连接SQL SERVER或者配置为连接字符串失败
使用IP连接SQL SERVER或者配置为连接字符串失败 情景一:当在webconfig文件中使用 <add key="ConnectionString" value=& ...
- .net连接sql server的几种连接字符串的写法
.net连接sql server的几种连接字符串的写法 1, 混合验证模式登录 server=电脑名 或 电脑IP;database=数据库名;uid=数据库登录名;password=数据库登录密码 ...
- SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database)
原文:SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database) 一.本文所涉及的内容(Contents) 本文所涉及的内容 ...
随机推荐
- Angular2入门系列教程1-使用Angular-cli搭建Angular2开发环境
一直在学Angular2,百忙之中抽点时间来写个简单的教程. 2016年是前端飞速发展的一年,前端越来越形成了(web component)组件化的编程模式:以前Jquery通吃一切的田园时代一去不复 ...
- Ubuntu下使用nvm
写在前面:刚写着写着博客就跨年了,希望新的一年大家万事如意,一切向"前"看! 安装 wget -qO- https://raw.githubusercontent.com/crea ...
- 关于解决python线上问题的几种有效技术
工作后好久没上博客园了,虽然不是很忙,但也没学生时代闲了.今天上博客园,发现好多的文章都是年终总结,想想是不是自己也应该总结下,不过现在还没想好,等想好了再写吧.今天写写自己在工作后用到的技术干货,争 ...
- 在SQL2008查找某数据库中的列是否存在某个值
在SQL2008查找某数据库中的列是否存在某个值 --SQL2008查找某数据库中的列是否存在某个值 create proc spFind_Column_In_DB ( @type int,--类型: ...
- 基于OpenCV的车辆检测与追踪的实现
最近老师布置了一个作业,是做一个基于视频的车辆检测与追踪,用了大概两周的时间做了一个简单的,效果不是很理想,但抑制不住想把自己的一些认识写下来,这里就把一些网络上的博客整理一下分享给大家,希望帮助到大 ...
- Partition1:新建分区表
未分区的表,只能存储在一个FileGroup中:对Table进行分区后,每一个分区都存储在一个FileGroup,或分布式存储在不同的FileGroup中.对表进行分区的过程,是将逻辑上完整的一个表, ...
- mysql 7下载安装及问题解决
mysql 7安装及问题解决 一.mysql下载 下载地址:https://www.mysql.com/downloads/ Community (GPL) Downloads MySQL Commu ...
- C#中如何给Excel添加水印
我们知道Microsoft Excel并没有内置的功能直接给Excel表添加水印,但是其实我们可以用其他变通的方式来解决此问题,如通过添加页眉图片或艺术字的方法来模仿水印的外观.所以在这篇文章中,我将 ...
- winform 窗体圆角设计
网上看到的很多winform窗体圆角设计代码都比较累赘,这里分享一个少量代码就可以实现的圆角.主要运用了System.Drawing.Drawing2D. 效果图 代码如下. private void ...
- .NET应用程序域
在.NET平台下,可执行程序并没有直接承载在Windows进程中,而非托管程序是直接承载的..NET可执行程序承载在进程的一个逻辑分区中,称之为应用程序域(AppDomain).一个进程可以包含多个应 ...