Guest User

Untitled

a guest
Oct 23rd, 2017
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.67 KB | None | 0 0
  1. -- PatternSplitLoop will split a string based on a pattern of the form
  2. -- supported by LIKE and PATINDEX
  3. --
  4. -- Created by: Dwain Camps 11-Oct-2012
  5. CREATE FUNCTION [dbo].[PatternSplitLoop]
  6. ( @String VARCHAR(400)
  7. ,@Pattern VARCHAR(500)
  8. ) RETURNS
  9. @Results TABLE ( ItemNumber INT
  10. ,Item VARCHAR(400)
  11. ,[Matched] INT )
  12. WITH SCHEMABINDING
  13. AS
  14. BEGIN;
  15.  
  16. -- DECLARE a couple of variables we'll need in our loop
  17. DECLARE
  18. @ItemNumber INT = 0
  19. , @Remaining VARCHAR(400) = ISNULL(@String, '')
  20. -- Create the "not pattern"
  21. , @NotPattern VARCHAR(500) = REPLACE(REPLACE(@Pattern, '[', '[^'), '^^', '')
  22. , @Matched INT
  23.  
  24. IF @String IS NULL OR @Pattern IS NULL
  25. INSERT INTO @Results SELECT NULL, NULL, NULL
  26.  
  27. WHILE DATALENGTH(@Remaining) > 0
  28. BEGIN
  29. SELECT @ItemNumber = @ItemNumber + 1
  30. -- The item returned from the cascaded CROSS APPLY b below
  31. ,@String = CASE
  32. -- When a+b = 1, then either a=1 and b=0 (the pattern was found but not pattern
  33. -- was not found) or a=0 and b=1 (the not pattern was found but pattern was
  34. -- not found).
  35. -- This means that no meaninful patterns are found in what remains so we’re done.
  36. WHEN a+b = 1 THEN @Remaining
  37. -- This case returns the chunk up to the start of the next pattern/not pattern
  38. WHEN (a=1 AND b>0) OR (b=1 AND a>0) THEN SUBSTRING(@Remaining, 1, CASE a
  39. WHEN 1 THEN b
  40. ELSE a
  41. END - 1)
  42. ELSE @Remaining
  43. END
  44. ,@Matched=CASE a WHEN 1 THEN 1 ELSE 0 END FROM (
  45. -- Find the next occurrence of the Pattern and the NotPattern
  46. SELECT PATINDEX(@Pattern, @Remaining)
  47. , PATINDEX(@NotPattern, @Remaining)
  48. ) a(a, b)
  49.  
  50. -- Now that we have our ItemNumber and Item (in @String) INSERT them into our results
  51. INSERT INTO @Results SELECT @ItemNumber, @String, @Matched
  52.  
  53. -- Find the remaining characters in the string
  54. SELECT @Remaining = CASE
  55. WHEN DATALENGTH(@Remaining) = DATALENGTH(@String) THEN ''
  56. ELSE SUBSTRING(@Remaining, DATALENGTH(@String)+1, DATALENGTH(@Remaining))
  57. END
  58. END
  59.  
  60. RETURN
  61. END
  62.  
  63. DECLARE @data TABLE
  64. (
  65. ItemNumber INT,
  66. Value VARCHAR(500),
  67. Formatted VARCHAR(100),
  68. Combined VARCHAR(500)
  69. )
  70.  
  71. INSERT INTO @data
  72. SELECT ItemNumber, Input, CASE WHEN Matched = 1 AND LTRIM(RTRIM(Item)) != '' THEN '[' + LTRIM(RTRIM(Item)) + ']' ELSE Item END as Arranged, '' FROM TABLE
  73. CROSS APPLY PatternSplitLoop(Input, '%[a-zA-Z ]%')
  74.  
  75. DECLARE @tmp TABLE(
  76. ID INT IDENTITY(1,1),
  77. DistinctValue VARCHAR(500)
  78. )
  79.  
  80. INSERT INTO @tmp(DistinctValue)
  81. SELECT Distinct Value FROM @data
  82.  
  83. DECLARE @minID INT = 1
  84. DECLARE @maxID INT = 0
  85. SELECT @maxID = COUNT(ID) FROM @tmp
  86. DECLARE @currValue VARCHAR(500) = ''
  87.  
  88. WHILE (@minID <= @maxID)
  89. BEGIN
  90.  
  91. SELECT @currValue = DistinctValue FROM @tmp WHERE ID = @minID
  92.  
  93. Update @data Set Combined = substring(
  94. (
  95. Select ' '+Formatted AS [text()]
  96. From @data a WHERE Value = @currValue
  97. ORDER BY a.ItemNumber
  98. For XML PATH ('')
  99. ), 2, 1000) FROM @data a INNER JOIN @tmp b ON a.Value = b.DistinctValue AND a.Value = @currValue
  100. WHERE ItemNumber = 1
  101.  
  102. SET @minID = @minID + 1
  103. SET @currValue = ''
  104. END
  105.  
  106. SELECT Value AS Input, REPLACE(Combined, '&#x20;', ' ') As Result FROM @data WHERE ItemNumber = 1
Add Comment
Please, Sign In to add comment