webentwicklung-frage-antwort-db.com.de

Wie lassen sich versteckte Zeichen im Ergebnis einer Abfrage in SQL Server (Query Analyzer) am besten identifizieren?

Wenn ich versuche, fehlerhafte Daten zu identifizieren (die häufig manuell überprüft und entfernt werden müssen), möchte ich, dass versteckte Zeichen wie TAB, Leertaste, Wagenrücklauf und Zeilenvorschub auf einfache Weise angezeigt werden. Gibt es einen eingebauten Weg dafür?

In einer ähnlichen Frage zum Stackoverflow bezüglich Oracle wurde eine DUMP-Funktion (Feldname) vorgeschlagen, aber ich weiß nicht, ob dies die Dinge einfacher machen würde, selbst wenn eine entsprechende Funktion in SQL Server vorhanden wäre, da ich die Zeichen sehen muss in ihrem Kontext.

Die beste Idee war, die erwarteten versteckten Zeichen durch sichtbare zu ersetzen:

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

Gibt es einen besseren Weg? Ich mag diese Art nicht, da es andere weniger verbreitete verborgene Zeichen geben kann, die von mir nicht berücksichtigt werden, wie z. B. vertikales TAB usw. Wenn Sie "verborgene Zeichen anzeigen" aktivieren, wie Sie es in fast jedem Texteditor tun können, Wäre so ein nettes Feature in SQL Server Query Analyzer, also erwarte ich fast, dass es auch in SQL Server irgendwie möglich ist ... oder zumindest, dass jemand eine noch bessere Idee hat als ich, diese Art von Leerraum zu zeigen die Info.

Ich habe gerade bemerkt, dass es eine integrierte Möglichkeit gibt, "Leerzeichen" zu sehen, nicht in SQL Query Analyzer, sondern in dem Teil der Benutzeroberfläche, der früher SQL Enterprise Manager war. Klicken Sie mit der rechten Maustaste auf eine Tabelle in SQL Klicken Sie in der Struktur des Management Studio-Objekt-Explorers auf "Top 200-Zeilen bearbeiten". Im Ergebnis wird der weiße Bereich (mindestens CR LF) als leere Quadrate angezeigt.

33
Andreas Jansson

Erstellen Sie eine Funktion, die alle Whitespace-Möglichkeiten anspricht, und aktivieren Sie nur die, die angemessen erscheinen:

SELECT dbo.ShowWhiteSpace(myfield) from mytable

Deaktivieren Sie nur die Whitespace-Fälle, auf die Sie testen möchten:


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

Um sie zu finden, können Sie dies verwenden

;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) + '%'
         )

Wenn Sie die EXISTS durch einen JOIN ersetzen, können Sie sie ERSETZEN, aber Sie erhalten mehrere Zeilen ... Ich kann mir keinen Ausweg vorstellen ...

9
gbn

Die Art und Weise, wie ich es tat, bestand darin, alle Daten auszuwählen

select * from myTable und dann mit der rechten Maustaste auf die Ergebnismenge klicken und "Ergebnisse speichern unter ..." als CSV-Datei auswählen.

Beim Öffnen der CSV-Datei in Notepad ++ wurden die Zeichen LF nicht in der SQL Server-Ergebnismenge angezeigt.

8
erik

Mit der Funktion DATALENGTH können Sie jederzeit feststellen, ob in Textfeldern zusätzliche Leerzeichen enthalten sind. Dadurch wird der Text nicht sichtbar, sondern es wird angezeigt, wo zusätzliche Leerzeichen vorhanden sind.

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

Dies ergibt 11 für BinaryLength und 10 für TextLength.

In einer Tabelle würde Ihr SQL so aussehen:

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

Diese Funktion ist in allen Versionen von SQL Server ab 2005 verfügbar.

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

Ich habe das gleiche Problem mit einem Charakter, mit dem ich es nie geschafft habe, mit einer where-Abfrage übereinzustimmen - CHARINDEX, LIKE, REPLACE usw. hat nicht funktioniert. Dann habe ich eine Brute-Force-Lösung verwendet, die schrecklich ist, schwer, aber funktioniert:

Schritt 1 : Erstellen Sie eine Kopie des gesamten Datensatzes. Verfolgen Sie die ursprünglichen Namen mit einer source_id, die auf den pk der Quellentabelle verweist (und bewahren Sie diese auf) Quell-ID in allen nachfolgenden Tabellen). Schritt 2 : LTRIM RTRIM die Daten, und ersetzen Sie alle doppelten Leerzeichen, Tabulatoren usw. (im Grunde alle CHAR (1) bis CHAR (32) durch ein Leerzeichen. Kleinschreibung des gesamten Satzes ebenfalls. Schritt 3 : Ersetzen Sie alle Sonderzeichen, die Sie kennen (erhalten Sie die Liste aller Anführungszeichen, doppelten Anführungszeichen usw.), durch etwas von AZ (ich schlage vor, z) Zeichen von AZ (mit geschachteltem REPLACE von REPLACE in einer Schleife). Schritt 4 : Aufteilen nach Word in eine zweite Kopie, wobei sich jedes Wort in einem eigenen befindet Zeile - die Teilung ist ein SUBSTRING basierend auf der Position der Leerzeichen - an dieser Stelle sollten wir diejenigen vermissen, bei denen es ein verstecktes Leerzeichen gibt, das wir vorher nicht markiert haben. Schritt 5 : Teilen Sie jedes Wort in eine dritte Kopie auf, wobei sich jeder Buchstabe in einer separaten Zeile befindet (ich weiß, dass es eine sehr große Tabelle bildet) - Verfolgen Sie den Zeichenindex jedes Buchstabens in a separate Spalte. Schritt 6 : Wählen Sie in der obigen Tabelle alles aus, was nicht LIKE [az] ist Liste der nicht identifizierten Zeichen, die wir ausschließen möchten.

Aus der Ausgabe von Schritt 6 haben wir genug Daten, um eine Folge von Teilzeichenfolgen der Quelle zu erstellen, um alles außer dem unbekannten Zeichen auszuwählen, das wir ausschließen möchten.

Anmerkung 1 : Je nach Größe des Originalausdrucks gibt es clevere Möglichkeiten, dies zu optimieren (Schritte 4, 5 und 6 können auf einmal ausgeführt werden) ).

Anmerkung 2 : Dies ist nicht sehr schnell, aber der schnellste Weg, dies für einen großen Datensatz zu erreichen, da die Zeilen in Wörter und Wörter aufgeteilt werden In Buchstaben wird durch einen Teilstring erzeugt, der die gesamte Tabelle in ein Zeichen schneidet. Dies ist jedoch ziemlich schwer zu bauen. Bei einem kleineren Satz kann es ausreichen, jeden Datensatz einzeln zu analysieren und nach Zeichen zu suchen, die nicht in einer Liste aller englischen Zeichen plus aller Sonderzeichen enthalten sind.

0
JeromeE