Please try the following method.
It will work starting from SQL Server 2008 onwards.
It is using XML, XQuery, and its FLWOR expression.
The algorithm is relatively simple:
- Cleanup input string via multiple
REPLACE()
function calls. (Big thanks goes to Viorel). - Conversion to XML data type via
CAST( ... AS XML)
. - Filtering out XML nodes that hold non-integer data type value via FLWOR expression.
- Sum remaining XML nodes with INT data type via XQuery
sum()
function. - Output the final result.
SQL
DECLARE @Goods TABLE(ID INT IDENTITY PRIMARY KEY, c31 NVARCHAR(MAX) NULL);
INSERT @Goods VALUES
('1. Black film -14rolls,red film 12rolls and blue film 22rolls 2.Some other things'),
('1.Dogs feed 15KG and 16KG; there are 125KG in paper pack, 2KG in plastic 2.Some data'),
('1. Film -151 rolls type 1 and 220 rolls type 2 2. Some data');
DECLARE @separator CHAR(1) = SPACE(1);
SELECT ID
, CAST('<root><r>' +
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(c31,
'-', @separator),
'rolls', @separator),
'KG', @separator),
'type 1', @separator),
'type 2', @separator), @separator, '</r><r>') + '</r></root>' AS XML)
.query('<root>
{
for $x in /root/r
return if (xs:int($x) instance of xs:int) then $x
else () (: filter out non-integers :)
}
</root>')
.query('sum(/root/r/text())').value('.', 'INT') AS [Result]
FROM @Goods
Output
+----+-----+
| ID | Sum |
+----+-----+
| 1 | 48 |
| 2 | 158 |
| 3 | 371 |
+----+-----+