我在外部站点上有一个表,我需要将其复制到本地数据库,但有一些转换。我必须大量修改的一个列叫做product_url。该URL的格式为site.com \ category \ sub-category \ brand \ model#。
我本地数据库中的表将有4列来保存这些数据。它们将是类别,子类别,品牌和型号#。所以,我将首先修剪site.com(我使用truncate做了这个),但现在我必须解析\ category \ sub-category \ brand \ model#
我发现了一个来自SO的UDF,我认为这会有所帮助。这是:
create function dbo.SplitString
(
@str nvarchar(4000),
@separator char(1)
)
returns table
AS
return (
with tokens(p, a, b) AS (
select
1,
1,
charindex(@separator, @str)
union all
select
p + 1,
b + 1,
charindex(@separator, @str, b + 1)
from tokens
where b > 0
)
select
p-1 zeroBasedOccurance,
substring(
@str,
a,
case when b > 0 then b-a ELSE 4000 end)
AS s
from tokens
)
GO
现在我无法使用此功能。可能是由于我缺乏UDF的经验。
以下是我现在所拥有的:
select s from
dbo.SplitString(select substring(product_url, 8, len(product_url))
from Products, '/')
where zeroBasedOccurance=0 AS Category
这显然在语法上不正确。
我想知道我是否会以最好的方式解决这个问题。我还不是一名DBA,所以我很难绕过这个问题。我只需要弄清楚如何为product_url表中的每一行应用此UDF~4次。
答案 0 :(得分:2)
不确定你的功能,但这是我的:
CREATE FUNCTION dbo.FN_PARSENAME(@chunk VARCHAR(4000), @delimiter CHAR(1), @index INT )
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE
@curIndex INT = 0,
@pos INT = 1,
@prevPos INT = 0,
@result VARCHAR(1000)
WHILE @pos > 0
BEGIN
SET @pos = CHARINDEX(@delimiter, @chunk, @prevPos);
IF(@pos > 0)
BEGIN -- Characters between position and previous position
SET @result = SUBSTRING(@chunk, @prevPos, @pos-@prevPos)
END
ELSE
BEGIN -- Last Delim
SET @result = SUBSTRING(@chunk, @prevPos, LEN(@chunk))
END
IF(@index = @curIndex)
BEGIN
RETURN @result
END
SET @prevPos = @pos + 1
SET @curIndex = @curIndex + 1;
END
RETURN '' -- Else Empty
END
你这样称呼:
SELECT Address_Line1 = dbo.fn_Parsename(Merged,'|', 0)
FROM Table
其中Merged是分隔的字段,'|'是分隔符,所以你要把它设为'\',0是你想要的字符串的哪一部分,0是第一个,在上面。
对于你的例子,它将是:
SELECT category = dbo.fn_Parsename(product_url,'\', 1)
, sub-category = dbo.fn_Parsename(product_url,'\', 2)
, brand = dbo.fn_Parsename(product_url,'\', 3)
, model# = dbo.fn_Parsename(product_url,'\', 4)
FROM Table
或者0-3取决于。
我很自信我从我发现的东西中调整过,甚至可能在SO上调整,但我不记得谁值得信任。