如何从URL获取某些值?

时间:2015-04-15 10:55:42

标签: sql sql-server sql-server-2008

鉴于此URL:

www.google.com/hsisn/-#++#/valuetoretrive/+#(#(/.html

值为4到5斜杠之间。 如何使用SQL Server 2008检索该特定值?

2 个答案:

答案 0 :(得分:1)

SQL Server中没有函数来获取值nth,唯一的函数是CHARINDEX,它将在指定的起始位置之后检索第一个实例。因此,利用它的唯一方法是级联每个找到的值,即:

  • 找到第一个"/"
  • 的位置
  • 在第一个{/ li>之后找到下一个"/"的位置
  • 在第二个{/ li>之后找到下一个"/"的位置

因此,每次计算都需要前一次计算的结果,如果您使用CROSS APPLY重复使用结果,则第5次出现的结果会相当混乱,但并非不可能。获得第4和第5次出现后的位置后,您可以使用SUBSTRING提取文本:

SELECT  t.url,
        Value = SUBSTRING(t.url, p4.Position, p5.Position - p4.Position - 1)
FROM    (SELECT url = 'URL:/www.google.com/hsisn/-#++#/valuetoretrive/+#(#(/.html') AS t
        CROSS APPLY (SELECT 1 + CHARINDEX('/', url)) AS p1 (Position)
        CROSS APPLY (SELECT 1 + CHARINDEX('/', url, p1.Position)) AS p2 (Position)
        CROSS APPLY (SELECT 1 + CHARINDEX('/', url, p2.Position)) AS p3 (Position)
        CROSS APPLY (SELECT 1 + CHARINDEX('/', url, p3.Position)) AS p4 (Position)
        CROSS APPLY (SELECT 1 + CHARINDEX('/', url, p4.Position)) AS p5 (Position);

<强>附录

如果您想要更灵活,即在第50和第51次出现之间获取文本,您拥有的另一个选项是使用分割功能。 The most efficient way to split strings is with a CLR function,但是用于此目的的下一个最佳T-SQL方法是使用数字表来拆分字符串,如果没有这个,则使用堆叠CTE创建自己的字符串。

为了完整的工作示例,我会假设您没有数字表并使用堆叠CTE。

CREATE FUNCTION dbo.Split (@StringToSplit VARCHAR(1000), @Delimiter CHAR(1))
RETURNS TABLE
AS
RETURN
(   WITH N1 (N) AS (SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) AS t (n)), 
    N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
    Numbers (N) AS (SELECT ROW_NUMBER() OVER(ORDER BY n1.N) FROM N1 CROSS JOIN N2 AS N2)
    SELECT  Position = ROW_NUMBER() OVER(ORDER BY n.N),
            Value = SUBSTRING(@StringToSplit, n.N, ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringToSplit, n.N + 1), 0), LEN(@StringToSplit)) - n.N)

    FROM    Numbers AS n
    WHERE   SUBSTRING(@Delimiter + @StringToSplit, n.N, 1) = @Delimiter
);

你可以简单地打电话:

DECLARE @Table TABLE (URL VARCHAR(255) NOT NULL);
INSERT @Table VALUES ('URL:/www.google.com/hsisn/-#++#/valuetoretrive/+#(#(/.html');
SELECT  s.*
FROM    @Table AS t
        CROSS APPLY dbo.Split(t.URL, '/') AS s;

这给了你:

Position    Value
---------------------
1           URL:
2           www.google.com
3           hsisn
4           -#++#
5           valuetoretrive
6           +#(#(
7           .htm

所以你可以通过添加where子句来简单地从中选择第5个值。:

DECLARE @Table TABLE (URL VARCHAR(255) NOT NULL);
INSERT @Table 
VALUES 
    ('URL:/www.google.com/hsisn/-#++#/valuetoretrive/+#(#(/.html'),
    ('URL:/www.google.com/hsisn/-#++#/valuetoretrive2/+#(#(/.html');
SELECT  t.URL, s.Value
FROM    @Table AS t
        CROSS APPLY dbo.Split(t.URL, '/') AS s
WHERE   s.Position = 5;

答案 1 :(得分:0)

如果您事先不知道网址的长度或要检索或削减位置的值,您可以使用此snipet

declare @uri varchar(max) = 'URL:/www.google.com/hsisn/-#++#/valuetoretrive/+#(#(/.html'

,@startAt int = 0
,@slashCount int = 0

while @slashCount < 5
begin

   set @startAt = CHARINDEX('/',@uri);
   set @slashCount = @slashCount + 1;

   if (@slashCount = 5)
      set @uri = SUBSTRING(@uri, 0, @startAt)
   else
      set @uri = SUBSTRING(@uri, @startAt + 1, LEN(@uri))


   -- debug info
   select @startAt, @slashCount, @uri
end

它分解了字符串,得到了斜线位置,直到找到#4和#5斜线并在它们之间得到任何东西。

<强>输出

5           1           www.google.com/hsisn/-#++#/valuetoretrive/+#(#(/.html
15          2           hsisn/-#++#/valuetoretrive/+#(#(/.html
6           3           -#++#/valuetoretrive/+#(#(/.html
6           4           valuetoretrive/+#(#(/.html
15          5           valuetoretrive

你也可以使用交叉应用而不是while循环来获得它但是这样你编码生病不需要变得大而且凌乱,以获得n&gt;之后的任何东西。 10,第n个slah。