Comment supprimer des caractères inconnus en utilisant T-SQL?

J'essaie de faire un script pour éliminer les caractères chinois dans une string et entre les caractères chinois que je veux supprimer. S'il vous plaît voir l'exemple ci-dessous. Je vous remercie.

select LTRIM(SUBSTRING('Tower 6A 第6A座', PATINDEX('%[a-zA-Z0-9]%', 'Tower 6A 第6A座'), LEN('Tower 6A 第6A座'))) select LTRIM(REPLACE(SUBSTRING('Tower 6A 第6A座', CHARINDEX(N'樓', 'Tower 6A 第6A座') + 1, LEN('Tower 6A 第6A座')), ' ', '')) 

Exemple de string:

 Tower 6A 第6A座Tower 3 第3座 

Mauvais résultat:

 Tower 6A ?6A? Tower6A?6A? Tower 3 ?3? Tower3?3? 

Bon résultat, je veux réaliser:

 Tower 6A Tower 6A Tower 3 Tower 3 

Essaye ça

  SELECT Replace(Replace('Tower 6A 第6A座','[^a-zA-Z0-9]+', ''),'?','') 

Ça a l'air bizarre mais fait le boulot. Cependant je ne countrais pas sur de grandes performances:

 ;WITH ssortingng AS ( SELECT N'Tower 6A 第6A座' s ), split AS ( select LEFT(s, 1) s_item, STUFF(s, 1, 1, N'') s from ssortingng union all select LEFT(s, 1), STUFF(s, 1, 1, N'') from split where s > '' ) , remove_non_ascii AS ( SELECT s_item, UNICODE(s_item) s_unicode FROM split WHERE UNICODE(s_item)<256 ) SELECT STUFF((SELECT s_item FROM remove_non_ascii FOR XML PATH, TYPE).value('.[1]', 'NVARCHAR(MAX)'), 1,0, ''); 

Ce qu'il fait:

  1. Divise les strings en rangées

  2. Élimine les caractères UNICODE supérieurs à 256 (vous pouvez bidouiller avec condition)

  3. Met la string set

Il utilise une requête récursive donc dans le cas de strings de plus de 100 caractères, vous devez augmenter le nombre de loops récursives en ajoutant: OPTION (MAXRECURSION n) (où n est une nouvelle quantité de loops récursives)

Essaye ça

 ;With cte(Data) AS ( SELECT 'Tower 6A 第6A座' UNION ALL SELECT 'Tower 3 第3座' ) SELECT CASE WHEN CHARINDEX('Tower', DATA)= 0 THEN 'Tower ' + DATA ELSE DATA END AS DATA FROM ( SELECT Split.a.value('.', 'VARCHAR(1000)') AS Data FROM ( SELECT CAST('<S>' + REPLACE(REPLACE(Data, '?', '</S><S>'),'','</S><S>') + '</S>' AS XML) AS Data FROM cte ) AS A CROSS APPLY Data.nodes('/S') AS Split(a) ) DT Where DT.Data <> '' 

Résultat

 DATA ---------- Tower 6A Tower 6A Tower 3 Tower 3 

En utilisant delimitedSplit8k, vous pouvez faire ceci:

 -- Sample data DECLARE @table TABLE (someid int identity, ssortingng nvarchar(100)); INSERT @table VALUES (N'Tower 6A 第6A座'), (N'Tower 3 第3座'); -- Solution WITH base AS ( SELECT someid, ItemNumber, itemClean = replace(item,'?','') FROM @table t CROSS APPLY dbo.delimitedSplit8K(t.ssortingng, ' ') ) SELECT someid, newssortingng = b1.itemClean + ' ' + b2.itemClean FROM base b1 CROSS APPLY ( SELECT itemClean FROM base b2 WHERE ItemNumber = 1 AND b1.someid = b2.someid ) b2 WHERE b1.ItemNumber > 1; 

Résultats:

 someid newssortingng ----------- --------- 1 6A Tower 1 6A Tower 2 3 Tower 2 3 Tower 

Une approche pour ce problème consiste à utiliser la capacité SQL Server 2016 pour exécuter le script R. Pour que cette méthode fonctionne, vous devrez vous assurer que les services R ont été installés sur votre server SQL Server, vous devrez également activer la procédure stockée 'sp_execute_external_script'. Activer les scripts externes comme suit:

 EXECUTE sp_configure; GO -- enable execution of external script add an argument: EXECUTE sp_configure 'external scripts enabled', 1; GO RECONFIGURE; GO 

Assurez-vous également que le service 'SQL Server Launchpad' est en cours d'exécution. Vous devrez peut-être également redémarrer SQL Server.

Si nous convertissons nos données d'input contenant les caractères chinois d'un Unicode en ASCII (VARCHAR), SQL Server convertira automatiquement les caractères chinois en points d'interrogation '?'. Ensuite, nous pouvons utiliser les capacités de correspondance de templates de langues R pour supprimer tout le text entre les points d'interrogation (formellement nos caractères chinois) selon l'exemple suivant:

 IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ExampleData]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[ExampleData]( [RawData] [nvarchar](100) NULL ) ON [PRIMARY] INSERT INTO ExampleData ( [RawData] ) VALUES ( N'Tower 6A 第6A座'); INSERT INTO ExampleData ( [RawData] ) VALUES ( N'Tower 3 第3座'); END DECLARE @inputQuery NVARCHAR(MAX) = N'SELECT CAST([RawData] AS VARCHAR(100)) as a FROM ExampleData' DECLARE @RScript NVARCHAR(MAX) = N' pattern <-"\\?.*\\?"; inData$a <- sub(pattern, "\\1", inData$a, perl = T ); outData <- inData;'; EXEC sp_execute_external_script @language = N'R' , @script = @RScript , @input_data_1 = @inputQuery , @input_data_1_name = N'inData' , @output_data_1_name=N'outData' with result sets ( (a varchar(300)));