SQL 将多个字符替换为单个字符

SQL Replace Multi chars with Single

我想用一个 * 值替换 SQL 中的所有数字。我研究了这个问题,但无法复制我发现的内容。我也觉得我把这个过程复杂化了。以下是我目前正在做的事情的分解:

查询:

CREATE TABLE #CMS_ERROR_LOG 
(
    ERROR_LOG_BODY NVARCHAR(MAX),
);

INSErT INTO #CMS_ERROR_LOG
select REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE ([ERROR_LOG_BODY], '0', '*'),
'1', '*'),
'2', '*'),
'3', '*'),
'4', '*'),
'5', '*'),
'6', '*'),
'7', '*'),
'8', '*'),
'9', '*')
FROM CMS_ERROR_LOG 
WHERE ERROR_LOG_MESSAGE = 'API Request Capture' 

SELECT
SUBSTRING([ERROR_LOG_BODY],1,CHARINDEX(',', [ERROR_LOG_BODY])-2) AS 'Request'
FROM #CMS_ERROR_LOG 
GROUP BY SUBSTRING([ERROR_LOG_BODY],1,CHARINDEX(',', [ERROR_LOG_BODY])-2)

我读到一些关于在替换语句中使用 # 仅替换为单个字符但无法使其工作的内容。

当前结果: [POST] URL: https://localhost:*****/api/authentication/authenticat

预期结果: [POST] URL: https://localhost:*/api/authentication/authenticat

更新: 我已经能够将数据格式化为更接近我需要的格式:

--DROP TABLE #CMS_ERROR_LOG

CREATE TABLE #CMS_ERROR_LOG 
(
    ERROR_LOG_BODY NVARCHAR(MAX),
);

INSErT INTO #CMS_ERROR_LOG
select 
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE 
([ERROR_LOG_BODY], '0', '*'),'1', '*'),'2', '*'),'3', '*'),'4', '*'),'5', '*'),'6', '*'),'7', '*'),'8', '*'),'9', '*')
FROM CMS_ERROR_LOG 
WHERE ERROR_LOG_MESSAGE = 'API Request Capture' 

--CLEAN UP
INSERT INTO #CMS_ERROR_LOG
SELECT
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE 
([ERROR_LOG_BODY], '**', '*'),'***', '*'),'****', '*'),'*****', '*'),'******', '*'),'*******', '*'),'********', '*'),'*********', '*')
FROM #CMS_ERROR_LOG

INSERT INTO #CMS_ERROR_LOG
SELECT
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE 
([ERROR_LOG_BODY], 'cases/*******', 'cases/*'),'contacts/******', 'contacts/*'),'LoanNumber=**********', 'LoanNumber=*'),'CourtCaseNumber=**', 'CourtCaseNumber=*'),'PropertyAddress=****', 'PropertyAddress=*'),'cases/**', 'cases/*'),'********', '*'),'*********', '*')
FROM #CMS_ERROR_LOG

SELECT
SUBSTRING([ERROR_LOG_BODY],1,CHARINDEX(',', [ERROR_LOG_BODY])-2) AS 'Request'
FROM #CMS_ERROR_LOG 
GROUP BY SUBSTRING([ERROR_LOG_BODY],1,CHARINDEX(',', [ERROR_LOG_BODY])-2)

DROP TABLE #CMS_ERROR_LOG

问题是,它仍然没有正确清理所有字符串: 例如,我最终得到这样的结果:

[GET] URL: https://masked.../masked.../api/cases/*****/contacts/*

[GET] URL: https://masked.../masked.../api/casefiles/******/loanRecords

更新: 我已经更新了我的 SQL。我能够解决我的问题。现在只是尝试清理未编辑的数据。很高兴有更好的替代方法。但是,我使用的是 2012 版,无法翻译。

新查询:

--DROP TABLE #CMS_ERROR_LOG

CREATE TABLE #CMS_ERROR_LOG 
(
    ERROR_LOG_BODY NVARCHAR(MAX),
);

INSErT INTO #CMS_ERROR_LOG
select 
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE 
([ERROR_LOG_BODY], '0', ''),'1', ''),'2', ''),'3', ''),'4', ''),'5', ''),'6', ''),'7', ''),'8', ''),'9', '')
FROM CMS_ERROR_LOG 
WHERE ERROR_LOG_MESSAGE = 'API Request Capture' 

--CLEAN UP
INSERT INTO #CMS_ERROR_LOG
SELECT
REPLACE
([ERROR_LOG_BODY], '//', '/*/')
FROM #CMS_ERROR_LOG

INSERT INTO #CMS_ERROR_LOG
SELECT
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE
([ERROR_LOG_BODY], 'https:/*/', 'https://'),'=&', '=*&'),'OfficeCode=NJ', 'OfficeCode=*'),'OfficeCode=VA', 'OfficeCode=*'),'OfficeCode=NY', 'OfficeCode=*')
FROM #CMS_ERROR_LOG

--Office Codes
INSERT INTO #CMS_ERROR_LOG
SELECT
REPLACE(REPLACE(REPLACE(REPLACE
([ERROR_LOG_BODY], 'OfficeCode=NJ', 'OfficeCode=*'),'OfficeCode=VA', 'OfficeCode=*'),'OfficeCode=NY', 'OfficeCode=*'),'OfficeCode=FL', 'OfficeCode=*')
FROM #CMS_ERROR_LOG

INSERT INTO #CMS_ERROR_LOG
SELECT
REPLACE(REPLACE(REPLACE(REPLACE
([ERROR_LOG_BODY], 'officeCode=NJ', 'OfficeCode=*'),'officeCode=VA', 'OfficeCode=*'),'officeCode=NY', 'OfficeCode=*'),'officeCode=FL', 'OfficeCode=*')
FROM #CMS_ERROR_LOG

SELECT
SUBSTRING([ERROR_LOG_BODY],1,CHARINDEX(',', [ERROR_LOG_BODY])-2) AS 'Request'
FROM #CMS_ERROR_LOG 
GROUP BY SUBSTRING([ERROR_LOG_BODY],1,CHARINDEX(',', [ERROR_LOG_BODY])-2)

DROP TABLE #CMS_ERROR_LOG

如果您使用的是 SQL Server 2017+,那么您就有我们的好朋友 TRANSLATE。否则嵌套的 REPLACE 就可以了。在这些示例中,我使用 NEWID 填充 table 以获取带有数字的随机文本,然后使用这两种技术 returning 您想要的内容。 (注意 re-producible 示例数据):

--==== 1. Re-producable Sample Data
DECLARE @t TABLE (SampleTxt VARCHAR(36));
INSERT @t SELECT TOP(10) NEWID() FROM sys.all_columns;

--==== 2. Solution #1: TRANSLATE 
SELECT 
  Original = t.SampleTxt,
  Cleaned = REPLACE(REPLACE(REPLACE(REPLACE(TRANSLATE(t.SampleTxt,'1234567890',
                    '**********'),'********','*'),'****','*'),'**','*'),'**','*')
FROM @t AS t;

--==== 3. Solution #2: Nested Replace for Number replacement
SELECT 
  Original = t.SampleTxt,
  Cleaned  = Transform2.Txt
FROM        @t AS t
CROSS APPLY(VALUES(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
                    REPLACE(REPLACE (t.SampleTxt,'0','*'),'1','*'),'2','*'),'3','*'),
                    '4', '*'),'5', '*'),'6','*'),'7','*'),'8','*'),'9','*'))
                   ) AS Transform1(Txt)
CROSS APPLY (VALUES(REPLACE(REPLACE(REPLACE(REPLACE(Transform1.Txt,
                    '********','*'),'****','*'),'**','*'),'**','*'))) AS Transform2(Txt);

两个return:

Original                               Cleaned
-------------------------------------- ------------------------------------
EF73E87F-868D-49E4-A347-CA42D5A378C0   EF*E*F-*D-*E*-A*-CA*D*A*C*
092CDE6E-C844-416A-B2DC-ACA948A38991   *CDE*E-C*-*A-B*DC-ACA*A*
D157AF76-35C0-401A-9CCC-5AC3F522A91B   D*AF*-*C*-*A-*CCC-*AC*F*A*B
00A0BD46-3A97-452E-806D-D5272C0BDF1C   *A*BD*-*A*-*E-*D-D*C*BDF*C
837B469C-7453-4B77-894B-9AEEDFFEF543   *B*C-*-*B*-*B-*AEEDFFEF*
9C92AE57-4AF5-4E82-A3C2-6D94DF9E3C3F   *C*AE*-*AF*-*E*-A*C*-*D*DF*E*C*F
58D8D873-D9E0-4582-867B-16810F10BD42   *D*D*-D*E*-*-*B-*F*BD*
7F80B552-C1D6-4A97-9C51-6FB8491D26B6   *F*B*-C*D*-*A*-*C*-*FB*D*B*
C466CADC-E38F-43A2-AA8F-CB0BDB0069DB   C*CADC-E*F-*A*-AA*F-CB*BDB*DB
1A5D6EC0-8335-485C-927F-D36E019EA6E1   *A*D*EC*-*-*C-*F-D*E*EA*E*