web-dev-qa-db-fra.com

Quelle est la meilleure façon d'identifier les caractères cachés dans le résultat d'une requête dans SQL Server (Query Analyzer)?

Lorsque j'essaie d'identifier des données erronées (nécessitant souvent un examen et une suppression manuels), j'aimerais avoir un moyen simple de voir les caractères cachés, tels que TAB, Espace, Retour chariot et Saut de ligne. Existe-t-il un moyen intégré pour cela?

Dans une question similaire ici sur stackoverflow, concernant Oracle, une fonction DUMP (nom de champ) a été suggérée, mais je ne sais pas si cela faciliterait les choses même si une fonction correspondante existait dans SQL Server, car j'ai besoin de voir les caractères dans leur contexte.

La meilleure idée que j'ai pu trouver était de remplacer les caractères cachés attendus par des caractères visibles, comme ceci:

SELECT REPLACE(REPLACE(REPLACE(REPLACE(myfield, ' ', '˙'), CHAR(13), '[CR]'), CHAR(10), '[LF]'), CHAR(9), '[TAB]') FROM mytable

Y a-t-il une meilleure façon? Je n'aime pas cette façon car il pourrait y avoir d'autres caractères cachés moins courants qui ne sont pas pris en compte par moi, tels que TAB vertical, etc. Activer "afficher les caractères cachés", comme vous pouvez le faire dans presque n'importe quel éditeur de texte, serait une si belle fonctionnalité dans SQL Server Query Analyzer, donc je m'attends presque à ce que cela puisse être fait d'une manière ou d'une autre dans SQL Server ... ou au moins que quelqu'un ait une idée encore meilleure que la mienne, pour montrer ce genre d'espace blanc Info.

Je viens de remarquer qu'il existe un moyen intégré de voir les "espaces blancs", non pas dans SQL Query Analyzer, mais dans la partie de l'interface qui était autrefois le gestionnaire SQL Enterprise. Cliquez avec le bouton droit sur une table dans SQL Arborescence de l'Explorateur d'objets de Management Studio et sélectionnez "Modifier les 200 premières lignes". Dans le résultat, un espace blanc (au moins CR LF) est visible sous forme de carrés vides.

33
Andreas Jansson

Créez une fonction qui aborde toutes les possibilités d'espace blanc et n'activez que celles qui vous semblent appropriées:

SELECT dbo.ShowWhiteSpace(myfield) from mytable

Ne commentez que les cas d'espaces que vous souhaitez tester:


CREATE FUNCTION dbo.ShowWhiteSpace (@str varchar(8000))
RETURNS varchar(8000)
AS
BEGIN
     DECLARE @ShowWhiteSpace varchar(8000);
     SET @ShowWhiteSpace = @str
     SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(32), '[?]')
     SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(13), '[CR]')
     SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(10), '[LF]')
     SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(9),  '[TAB]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(1),  '[SOH]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(2),  '[STX]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(3),  '[ETX]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(4),  '[EOT]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(5),  '[ENQ]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(6),  '[ACK]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(7),  '[BEL]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(8),  '[BS]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(11), '[VT]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(12), '[FF]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(14), '[SO]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(15), '[SI]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(16), '[DLE]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(17), '[DC1]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(18), '[DC2]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(19), '[DC3]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(20), '[DC4]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(21), '[NAK]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(22), '[SYN]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(23), '[ETB]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(24), '[CAN]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(25), '[EM]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(26), '[SUB]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(27), '[ESC]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(28), '[FS]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(29), '[GS]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(30), '[RS]')
--   SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(31), '[US]')
     RETURN(@ShowWhiteSpace)
END
48

Pour les trouver, vous pouvez utiliser ceci

;WITH cte AS
(
   SELECT 0 AS CharCode
   UNION ALL
   SELECT CharCode + 1 FROM cte WHERE CharCode <31
)
SELECT
   *
FROM
   mytable T
     cross join cte
WHERE
   EXISTS (SELECT *
        FROM mytable Tx
        WHERE Tx.PKCol = T.PKCol
             AND
              Tx.MyField LIKE '%' + CHAR(cte.CharCode) + '%'
         )

Remplacer les EXISTS par un JOIN vous permettra de les REMPLACER, mais vous obtiendrez plusieurs lignes ... Je ne peux pas penser à un moyen de contourner cela ...

9
gbn

Ils l'ont fait en sélectionnant toutes les données

select * from myTable puis en cliquant avec le bouton droit sur le jeu de résultats et en choisissant "Enregistrer les résultats sous ..." un fichier csv.

En ouvrant le fichier csv dans Notepad ++, j'ai vu les caractères LF non visibles dans le jeu de résultats SQL Server.

8
erik

Vous pouvez toujours utiliser la fonction DATALENGTH pour déterminer si vous avez des caractères d'espace blanc supplémentaires dans les champs de texte. Cela ne rendra pas le texte visible mais vous montrera où il y a des caractères d'espace blanc supplémentaires.

    SELECT DATALENGTH('MyTextData ') AS BinaryLength, LEN('MyTextData ') AS TextLength

Cela produira 11 pour BinaryLength et 10 pour TextLength.

Dans une table, votre SQL aimerait ceci:

    SELECT * 
    FROM tblA
    WHERE DATALENGTH(MyTextField) > LEN(MyTextField)

Cette fonction est utilisable dans toutes les versions de SQL Server à partir de 2005.

5
Don Kidd
select myfield, CAST(myfield as varbinary(max)) ...
0
Oleg Dok

J'ai rencontré le même problème avec un personnage que je n'ai jamais réussi à faire correspondre avec une requête where - CHARINDEX, LIKE, REPLACE, etc. n'a pas fonctionné. Ensuite, j'ai utilisé une solution de force brute qui est horrible, lourde mais qui fonctionne:

Étape 1 : faites une copie de l'ensemble de données complet - gardez une trace des noms originaux avec un source_id référençant le paquet de la table source (et gardez ceci id source dans toutes les tables suivantes). Étape 2 : LTRIM RTRIM les données, et remplacez tous les espaces doubles, tabulations, etc. (essentiellement tous les CHAR (1) à CHAR (32) par un espace. Mettez également en minuscules l'ensemble. Étape 3 : remplacez tous les caractères spéciaux que vous connaissez (obtenez la liste de toutes les citations, guillemets doubles, etc.) par quelque chose d'az (je suggère z) .Remplacez fondamentalement tout ce qui n'est pas l'anglais standard caractères par az (en utilisant le REMPLACEMENT imbriqué du REMPLACEMENT dans une boucle). Étape 4 : divisé par Word en une deuxième copie, où chaque mot est dans un séparé ligne - le fractionnement est un SUBSTRING basé sur la position des caractères d'espace - à ce stade, nous devrions manquer ceux où il y a un espace caché que nous n'avons pas capturé plus tôt. Étape 5 : divisez chaque mot en une troisième copie, où chaque lettre est sur une ligne distincte (je sais que cela fait un très grand tableau) - gardez une trace du caractère de chaque lettre dans un colonne séparée. Étape 6 : Sélectionnez tout ce qui n'est pas LIKE [az] dans le tableau ci-dessus. liste des caractères non identifiés que nous voulons exclure.

De la sortie de l'étape 6, nous avons suffisamment de données pour créer une série de sous-chaînes de la source pour tout sélectionner sauf le caractère inconnu que nous voulons exclure.

Note 1 : il existe des moyens intelligents d'optimiser cela, en fonction de la taille de l'expression originale (les étapes 4, 5 et 6 peuvent être effectuées en une seule fois ).

Note 2 : ce n'est pas très rapide, mais le moyen le plus rapide de le faire pour un grand ensemble de données, car la division des lignes en mots et en mots en lettres se fait par sous-chaîne, qui tranche toute la table en une seule tranche de caractère. Cependant, c'est assez lourd à construire. Avec un ensemble plus petit, il peut être suffisant d'analyser chaque enregistrement un par un et de rechercher un caractère qui ne figure pas dans une liste de tous les caractères anglais plus tous les caractères spéciaux.

0
JeromeE