SQLSERVER根据特定字符截取字符串

写SQL时经常会遇到需要根据特定字符去截取原始字符串的情况,简单总结一下。

首先,准备工作:

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[MY_TEST](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FIELDSVALUE] [nvarchar](255) NULL,
CONSTRAINT [PK_MY_TEST] 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];

INSERT INTO [dbo].[MY_TEST]
([FIELDSVALUE])
VALUES
(‘5yt5g/h.7yj/5e//435tsd‘),
(‘//.we4rf6@gf/76iyg5t/ihjk//6yjf‘),
(‘435t/56yg/53ytdh/56uyj/6ury/5utyjf/6uyrh/65uyhf/74urh/q4rtegsd//‘),
(‘34tg3yuh/564yg‘),
(‘65uej/78irj/658jg44g/6jy/‘),
(‘34t/5euyhd/45yh/5yrth/5tr‘),
(‘192.168.1.1‘);

执行查询,

SQLSERVER根据特定字符截取字符串

 

 自此,准备工作完成。

 

首先,我想看一下ID为3的那一行,‘/’总共出现了几次:

SELECT len([FIELDSVALUE])-len(replace([FIELDSVALUE], ‘/‘, ‘‘)) AS [COUNTS] FROM [dbo].[MY_TEST] WHERE [ID] = 3;

SQLSERVER根据特定字符截取字符串

 

 接着,我想看看 ‘/‘ 在ID=1时,首次出现的位置:

SELECT CHARINDEX(‘/‘,[FIELDSVALUE]) AS [INDEXOF] FROM [dbo].[MY_TEST] WHERE [ID] =1;

SQLSERVER根据特定字符截取字符串

 

 然后,第二次出现的位置:

SELECT CHARINDEX(‘/‘,[FIELDSVALUE],CHARINDEX(‘/‘,[FIELDSVALUE])+1) AS [INDEXOF] FROM [dbo].[MY_TEST] WHERE [ID] = 1;

SQLSERVER根据特定字符截取字符串

 

 

那么,想知道ID=1时,第一个‘/‘和第二个‘/‘之间的字串就很简单了:

SELECT SUBSTRING([FIELDSVALUE],CHARINDEX(‘/‘,[FIELDSVALUE])+1,
CHARINDEX(‘/‘,[FIELDSVALUE],CHARINDEX(‘/‘,[FIELDSVALUE])+1)-CHARINDEX(‘/‘,[FIELDSVALUE])-1)
AS [NEWSTRING]
FROM [dbo].[MY_TEST]
WHERE [ID] = 1;

SQLSERVER根据特定字符截取字符串

 

 

如果指定的分隔符确定不超过3个的话,还有个简单的函数 PARSENAME ,该函数是用于域名解析的,先看下效果:

SELECT [ID], [FIELDSVALUE],
PARSENAME(REPLACE([FIELDSVALUE],‘/‘,‘.‘),4) AS [第四段],
PARSENAME(REPLACE([FIELDSVALUE],‘/‘,‘.‘),3) AS [第三段],
PARSENAME(REPLACE([FIELDSVALUE],‘/‘,‘.‘),2) AS [第二段],
PARSENAME(REPLACE([FIELDSVALUE],‘/‘,‘.‘),1) AS [第一段]
FROM [dbo].[MY_TEST]
WHERE [ID] = 7;

SQLSERVER根据特定字符截取字符串

 

 可以看出,PARSENAME 函数解析域名时,是从后向前解析的,微软官方提供的解释为:PARSENAME ( ‘object_name‘ , object_piece )

‘ object_name ‘
是要为其检索指定对象部分的对象的名称。

object_piece
是要返回的对象部分。object_piece的类型为int,值可以为1,2,3,4

SQLSERVER根据特定字符截取字符串

 

 

但是,有时候也会碰到这样的情况:截取指定字符第N次出现和第N+1次出现时的字串。这个时候,单纯的写查询SQL就会很繁琐,就可以使用存储过程去实现,

比如,我想知道 [ID] = 3 时,‘/‘ 字符第6次和第7次出现时的中间字串。

先创建个存储过程:

IF EXISTS(SELECT 1 FROM SYSOBJECTS WHERE NAME=‘SELECTINDEX‘)
DROP FUNCTION SELECTINDEX
GO
CREATE FUNCTION SELECTINDEX(@STRINGS NVARCHAR(200),@STRING NVARCHAR(10),@INDEX INT)
--@STRINGS:待查找字符串,@INDEX:位置
RETURNS INT
AS
BEGIN
DECLARE
@I INT,--当前找到第@I个
@POSITION INT--所在位置
SET @POSITION=1;
SET @I=0;
WHILE CHARINDEX(@STRING,@STRINGS,@POSITION)>0
BEGIN
SET @POSITION=CHARINDEX(@STRING,@STRINGS,@POSITION)+1;
SET @I=@I+1;
IF @I=@INDEX
BEGIN
RETURN @POSITION-1;
END
END
RETURN 0;--0表示未找到
END
GO

然后就简单了:

SELECT SUBSTRING([FIELDSVALUE],
[dbo].SELECTINDEX([FIELDSVALUE],‘/‘,6)+1,
[dbo].SELECTINDEX([FIELDSVALUE],‘/‘,7)-([dbo].SELECTINDEX([FIELDSVALUE],‘/‘,6)+1))
AS [NEWSTRING]
FROM [dbo].[MY_TEST]
WHERE [ID] = 3

SQLSERVER根据特定字符截取字符串

 

 暂时先总结这么多,以后再补充。

 

SQLSERVER根据特定字符截取字符串

上一篇:access 注入


下一篇:Java IO详解(一)------字节输入输出流