Below is a fraction of a stored procedure I am writing to parse out some non-normalized data into a more normal form.
What we have are data records containing two specific fields: MMYString (varchar 255) and MMYLongString (text). These hold strings containing the make, model, and year of vehicles that the product can be used with. The MMY strings look like this:
HONDA;CRF250R;2006|HONDA;C
RF250R;200
5|HONDA;CR
F250R;2004
The information will be in MMYString unless the data length is more than 255 characters. Then the data will be in MMYLongString, and no information will be in MMYString. Note that we have data strings well over 30kb long for some cases.
I have created a routine that will strip the information out of a text field, and incorporated that into my code, a piece of which is below. I am looking for any assistance in optimizing this routine, since I would like to run it nightly, and the process takes over an hour at this time.
--------------------------
----------
----------
--
DECLARE @text table(txt text)
SET @separator = '|'
DECLARE c_Parse CURSOR FOR
SELECT p.ProductID, lastModificationDate
FROM SearchJoin sj
INNER JOIN product P
ON sj.productid = P.productId
WHERE MMYExists = 'Y'
AND lastmodificationdate >= @Cutoff
ORDER BY p.ProductID
OPEN c_Parse
FETCH NEXT FROM c_Parse INTO @PID, @LMD
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @WorkStr = ISNULL(MMYString, '') FROM searchJoin WHERE productid = @Pid
IF @WorkStr = '' -- Data in mmylongstring
BEGIN
INSERT INTO @text
SELECT MMYLongString AS Txt
FROM SearchJoin sj
WHERE sj.ProductID = @PID
SELECT @i = 1,
@len = datalength(txt),
@curpos = 1
FROM @text
WHILE @curpos <= @len -- Parse out a text field of arbitrary length in the
BEGIN
select @lastpos=@curpos
,@patindex=patindex('%'+@s
eparator+'
%',substri
ng(txt,@la
stpos+1,10
1))
,@patindex=case @patindex when 0 then @len-@lastpos+1 else @patindex END
,@val=substring(txt,@lastp
os,@patind
ex)
,@curpos=@lastpos+@patinde
x+1
FROM @text
If @Val LIKE '_%;_%;[1-2][0-9][0-9][0-9
]' AND @val not like '%;%;%;%'
BEGIN
Set @Ptr = charindex(';',@val)
Set @Make = Left(@Val, @Ptr - 1)
SET @Ptr2 = CHARINDEX(';', @val, @ptr + 1)
Set @Model = Substring(@Val, @Ptr+1, @Ptr2 - (@ptr + 1))
Set @Year = SUBSTRING(@val, @Ptr2 + 1, LEN(@Val))
SET @NewID = 0
SELECT @NewID = MMYID
FROM MMY
WHERE Make = @Make
AND Model = @Model
AND mmy.Year = @Year
IF IsNull(@NewID, 0) = 0
BEGIN
INSERT INTO MMY (Make, Model, Year)
VALUES (@Make, @Model, @Year)
END
IF NOT EXISTS (SELECT * FROM #Product_MMY WHERE ProductID = @PID AND MMYID = @NewID)
INSERT INTO #Product_mmy (ProductID, MMYID, LastModificationdate)
VALUES (@PID, @NewID, @LMD)
END
END
DELETE
FROM @Text
END
ELSE
BEGIN
WHILE LEN(@WorkStr)>0
BEGIN
Set @Ptr = CHARINDEX(@Separator, @WorkStr, @Ptr2)
IF @Ptr = 0
BEGIN
SET @Val = @WorkStr
SET @WorkStr = ''
END
ELSE
BEGIN
SET @Val = LEFT(@WorkStr, @ptr-1)
SET @WorkStr = SUBSTRING(@WorkStr, @Ptr+1, LEN(@WorkStr))
END
Set @Make = Left(@Val, @Ptr - 1)
SET @Ptr2 = CHARINDEX(';', @val, @ptr + 1)
Set @Model = Substring(@Val, @Ptr+1, @Ptr2 - (@ptr + 1))
Set @Year = SUBSTRING(@val, @Ptr2 + 1, LEN(@Val))
SET @NewID = 0
SELECT @NewID = MMYID
FROM MMY
WHERE Make = @Make
AND Model = @Model
AND mmy.Year = @Year
IF IsNull(@NewID, 0) = 0
BEGIN
INSERT INTO MMY (Make, Model, Year)
VALUES (@Make, @Model, @Year)
END
IF NOT EXISTS (SELECT * FROM #Product_MMY WHERE ProductID = @PID AND MMYID = @NewID)
INSERT INTO #Product_mmy (ProductID, MMYID, LastModificationdate)
VALUES (@PID, @NewID, @LMD)
END
END
FETCH NEXT FROM c_Parse INTO @PID, @LMD
END
Start Free Trial