SQL Server không hỗ trợ thay thế các mẫu của nhiều ký tự - vì vậy để thực hiện thông qua REPLACEsẽ có khả năng 10 thao tác.
Với ý nghĩ đó, một cách làm sẽ là CTE đệ quy để xử lý các chữ số 0-9 theo tuần tự.
Nó thực hiện thay thế và sau đó kiểm tra độ dài của chuỗi trước và sau để biết có bao nhiêu ký tự của số đó và những gì cần phải được thêm vào tổng số.
DECLARE @Input VARCHAR(8000) = 'GR35hc7vdH35';
WITH R(Level,Input,Accumulator,StringLength)
AS (SELECT 0,
Input,
0,
DATALENGTH(Input)
FROM (SELECT REPLACE(@Input, '0', '')) D(Input)
UNION ALL
SELECT NewLevel,
NewInput,
Accumulator + NewLevel * ( StringLength - NewStringLength ),
NewStringLength
FROM R
CROSS APPLY (SELECT Level + 1) C(NewLevel)
CROSS APPLY (SELECT REPLACE(Input, NewLevel, '')) C2(NewInput)
CROSS APPLY (SELECT DATALENGTH(NewInput)) C3(NewStringLength)
WHERE NewLevel <= 9)
SELECT Input AS Col1,
Accumulator AS Col2
FROM R
WHERE Level = 9;
Hoặc bạn có thể sử dụng CLR và các biểu thức chính quy (phiên bản tương thích SQL Server 2012).
using System;
using System.Data.SqlTypes;
using System.Collections;
using System.Text.RegularExpressions;
public partial class UserDefinedFunctions
{
private static readonly Regex digitRegex = new Regex(@"[\d]", RegexOptions.Compiled);
[Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "FillRow",
TableDefinition = @"Stripped NVARCHAR(MAX),
Total INT")]
public static IEnumerable ReplaceAndTotalise(SqlString input)
{
if (!input.IsNull)
{
int total = 0;
string stripped = digitRegex.Replace((string)input, match =>
{
total += int.Parse(match.Value);
return string.Empty;
});
yield return new Tuple<string, int>(stripped, total);
}
}
public static void FillRow(object resultObject, out SqlString stripped, out SqlInt32 total)
{
var result = (Tuple<string, int>)resultObject;
stripped = result.Item1;
total = result.Item2;
}
}
Cách sử dụng ví dụ
SELECT Stripped,
Total
FROM [dbo].[ReplaceAndTotalise]('GR35hc7vdH35')