我在外部站点上有一张表,需要将其复制到本地数据库,但是需要进行一些转换。我必须大量修改的列之一称为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次。
不确定您的功能,但这是我的:
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
SELECT Address_Line1 = dbo.fn_Parsename(Merged,'|', 0) FROM Table
其中合并的字段是定界的,“ |” 是定界符,因此您将其定为“ \”,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上)中改编了该内容,但我不记得谁应该得到认可。