SQL Server unterstützt das Ersetzen von Mustern mit mehreren Zeichen nicht. Wenn Sie dies über tun REPLACE, sind möglicherweise 10 Vorgänge erforderlich.
In diesem Sinne wäre eine Möglichkeit ein rekursiver CTE, die Ziffern 0-9 nacheinander zu verarbeiten.
Es ersetzt und überprüft dann die Länge der Vorher- und Nachher-Zeichenfolgen, um festzustellen, wie viele Zeichen dieser Zahl vorhanden waren und was zur Gesamtsumme hinzugefügt werden muss.
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;
Oder Sie können CLR und reguläre Ausdrücke verwenden (SQL Server 2012-kompatible Version).
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;
}
}
Beispiel Verwendung
SELECT Stripped,
Total
FROM [dbo].[ReplaceAndTotalise]('GR35hc7vdH35')