Ho una tabella con un paio di migliaia di righe. I campi descrizione e riepilogo sono NTEXT e talvolta hanno caratteri non ASCII. Come posso individuare tutte le righe con caratteri non ASCII?Come posso trovare caratteri Unicode/non ASCII in un campo NTEXT in una tabella di SQL Server 2005?
Come posso trovare caratteri Unicode/non ASCII in un campo NTEXT in una tabella di SQL Server 2005?
risposta
Prima costruisci una stringa con tutti i caratteri che non ti interessano (l'esempio usa l'intervallo 0x20 - 0x7F o 7 bit senza i caratteri di controllo). Ogni carattere è preceduto da |, per l'uso nella clausola escape dopo.
-- Start with tab, line feed, carriage return
declare @str varchar(1024)
set @str = '|' + char(9) + '|' + char(10) + '|' + char(13)
-- Add all normal ASCII characters (32 -> 127)
declare @i int
set @i = 32
while @i <= 127
begin
-- Uses | to escape, could be any character
set @str = @str + '|' + char(@i)
set @i = @i + 1
end
Il snippet successivo ricerca qualsiasi carattere che non sia nell'elenco. La% corrisponde a 0 o più caratteri. [] Corrisponde a uno dei caratteri all'interno di [], ad esempio [abc] corrisponde a a, boc. Il^nega l'elenco, ad esempio [^ abc] corrisponde a tutto ciò che non è a, b, o c.
select *
from yourtable
where yourfield like '%[^' + @str + ']%' escape '|'
è necessario il carattere di escape perché altrimenti alla ricerca di personaggi come],% o _ sarebbe rovinare l'espressione LIKE.
Spero che questo sia utile, e grazie al commento di JohnFX sull'altra risposta.
probabilmente non è la soluzione migliore, ma forse una query come:
SELECT *
FROM yourTable
WHERE yourTable.yourColumn LIKE '%[^0-9a-zA-Z]%'
Sostituire l'espressione "0-9a-zA-Z" con qualcosa che cattura il set ASCII completo (o un sottoinsieme che il vostro i dati contengono).
Non corrisponde solo alle righe che contengono caratteri ASCII, al contrario solo caratteri ASCII? – Andomar
Il marcatore^nella parte anteriore dell'espressione significa NOT, quindi no. Avrebbe ottenuto qualsiasi riga che avesse almeno un carattere che non era compreso negli intervalli specificati. – JohnFx
Come posso inserire il set completo di ascii in quell'espressione? sono i dati HTML che sto osservando così "/><'etc ... è lì dentro. – TheSoftwareJedi
La mia risposta precedente confondeva i dati UNICODE/non-UNICODE. Ecco una soluzione che dovrebbe funzionare per tutte le situazioni, anche se sto ancora incontrando alcune anomalie. Sembra che certi caratteri unicode non ASCII per i caratteri in apice siano confusi con il carattere numerico attuale. Potresti essere in grado di giocare con le regole di confronto per aggirare il problema.
Speriamo che tu abbia già una tabella di numeri nel tuo database (possono essere molto utili), ma nel caso in cui ho incluso il codice per riempirlo parzialmente.
Potrebbe anche essere necessario per giocare con l'intervallo numerico, dal momento che i caratteri Unicode possono andare oltre 255.
CREATE TABLE dbo.Numbers
(
number INT NOT NULL,
CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (number)
)
GO
DECLARE @i INT
SET @i = 0
WHILE @i < 1000
BEGIN
INSERT INTO dbo.Numbers (number) VALUES (@i)
SET @i = @i + 1
END
GO
SELECT *,
T.ID, N.number, N'%' + NCHAR(N.number) + N'%'
FROM
dbo.Numbers N
INNER JOIN dbo.My_Table T ON
T.description LIKE N'%' + NCHAR(N.number) + N'%' OR
T.summary LIKE N'%' + NCHAR(N.number) + N'%'
and t.id = 1
WHERE
N.number BETWEEN 127 AND 255
ORDER BY
T.id, N.number
GO
Il modo in cui lo capisco, ASCII è 7 bit e varchar è 8 bit. Quindi varchar può ancora memorizzare molti caratteri che non sono ascii, come ä o é. – Andomar
Sto vedendo gli stessi risultati. Questo non funziona. – TheSoftwareJedi
ASCII esteso è 8 bit, che è ciò a cui alcune persone si riferiscono quando dicono "ASCII". Modificherò il post anche per limitare il normale ASCII. –
- Questo è un modo molto, molto inefficiente di farlo, ma dovrebbe essere OK per - Tavolini Utilizza una tabella ausiliaria di numeri secondo Itzik Ben-Gan e semplicemente - cerca i caratteri con il bit 7 impostato.
SELECT *
FROM yourTable as t
WHERE EXISTS (SELECT *
FROM msdb..Nums as NaturalNumbers
WHERE NaturalNumbers.n < LEN(t.string_column)
AND ASCII(SUBSTRING(t.string_column, NaturalNumbers.n, 1)) > 127)
Tecnicamente, credo che un NCHAR (1) è un carattere ASCII valida se & solo se UNICODE (@NChar) < 256 e ASCII (@NChar) = Unicode (@NChar) anche se questo potrebbe non essere esattamente quello che volevi. Quindi questa sarebbe una soluzione corretta:
;With cteNumbers as
(
Select ROW_NUMBER() Over(Order By c1.object_id) as N
From sys.system_columns c1, sys.system_columns c2
)
Select Distinct RowID
From YourTable t
Join cteNumbers n ON n <= Len(CAST(TXT As NVarchar(MAX)))
Where UNICODE(Substring(TXT, n.N, 1)) > 255
OR UNICODE(Substring(TXT, n.N, 1)) <> ASCII(Substring(TXT, n.N, 1))
Questo dovrebbe anche essere molto veloce.
ASCII è solo fino a 127. Anche il tuo numero cte è strano - la soluzione finale dovrebbe usare una tabella di numeri preesistente invece di essa. Altrimenti, è così che lo farei. –
FYI: "Non sembrare strano" non è un criterio che io (o la maggior parte degli uber-geek di questo sito) ci tengo davvero. E il vantaggio di non utilizzare una tabella di numeri preesistente, è che funziona anche se la tabella non è preesistente (cosa che di solito non funziona). Infine, se metti alla prova la mia soluzione, scoprirai che funziona a un livello comparabile ea volte persino migliore di una tabella di numeri preesistente. – RBarryYoung
Non voglio davvero discutere - sono per lo più d'accordo con la tua soluzione. Ma "strano" di solito è difficile da leggere e irrinunciabile. È così che intendevo. Inoltre, non è ASCIUTTO se hai due query diverse che richiedono numeri: devi scrivere due volte la C++ non più gestibile. Leggere i numeri di riga da un join di system_columns su se stesso non è molto semplice, ma leggere i numeri da una tabella di numeri sarebbe molto facile eseguire il debug. –
volte ho usato questa dichiarazione "cast" di trovare caratteri "strani"
select
*
from
<Table>
where
<Field> != cast(<Field> as varchar(1000))
ho iniziato con la soluzione di @ CC1960 ma ho trovato un interessante caso d'uso che ha causato il fallimento.Sembra che SQL Server equiparerà determinati caratteri Unicode alle loro approssimazioni non Unicode. Ad esempio, SQL Server considera il carattere Unicode "fullwidth comma" (http://www.fileformat.info/info/unicode/char/ff0c/index.htm) lo stesso di una virgola ASCII standard se confrontato in una clausola WHERE.
Per aggirare questo problema, fare in modo che SQL Server confronti le stringhe come binario. Ma ricordate, nvarchar e varchar binari non corrispondono up (16-bit vs 8-bit), quindi è necessario convertire il vostro varchar indietro fino alla nvarchar di nuovo prima di fare il confronto binario:
select *
from my_table
where CONVERT(binary(5000),my_table.my_column) != CONVERT(binary(5000),CONVERT(nvarchar(1000),CONVERT(varchar(1000),my_table.my_column)))
Se sei cercando un carattere unicode specifico, potresti usare qualcosa come sotto.
select Fieldname from
(
select Fieldname,
REPLACE(Fieldname COLLATE Latin1_General_BIN,
NCHAR(65533) COLLATE Latin1_General_BIN,
'CustomText123') replacedcol
from table
) results where results.replacedcol like '%CustomText123%'
Qui ya go:
SELECT *
FROM Objects
WHERE
ObjectKey LIKE '%[^0-9a-zA-Z !"#$%&''()*+,\-./:;<=>[email protected]\[\^_`{|}~\]\\]%' ESCAPE '\'
- 1. Concatenate ntext in SQL Server 2005
- 2. Come creare un tipo di tabella in SQL Server 2005
- 3. Come trovare la somma di più colonne in una tabella in SQL Server 2005?
- 4. Come posso impostare un campo calcolato semplice in SQL Server?
- 5. Trova una tabella su più database SQL SERVER 2005
- 6. Isoweek in SQL Server 2005
- 7. Come posso creare un trigger disabilitato in SQL Server 2005?
- 8. come trovare chi blocca chi in SQL Server 2005
- 9. SQL Server 2005 e ambito tabella temporaneo
- 10. Come utilizzare BIT in SQL Server 2005
- 11. MS SQL Server da NTEXT a INT
- 12. Dimensioni del campo VARBINARY in SQL Server 2005
- 13. Trova caratteri non ASCII nelle colonne varchar utilizzando SQL Server
- 14. SQL Server 2005 ROW_NUMBER() senza ORDER BY
- 15. SQL Server 2005 replica
- 16. Come definire ENUM in SQL Server 2005?
- 17. Database SQL Server 2005 'In Recovery'
- 18. Come posso visualizzare una tabella interna in SQL Server 2008?
- 19. Come contare ogni record in ciascuna tabella in un database di SQL Server 2005?
- 20. Come cadere proprietà IDENTITY di colonna in SQL Server 2005
- 21. sottoquery in UPDATE SET (sql server 2005)
- 22. Come posso creare una tabella utilizzando ASCII in una console?
- 23. Come trovare i tipi di colonna derivati di una vista in SQL Server 2005?
- 24. Verificare che SQL Server 2005 XML campo è vuoto
- 25. Come convertire NVARCHAR separati da virgola in record di tabella in SQL Server 2005?
- 26. Come posso usare if dopo un CTE (SQL Server 2005)
- 27. SQL Server 2005 - rimozione dei trigger di tabella?
- 28. Rinominare una colonna in MS SQL Server 2005
- 29. Come inserire un dataframe in una tabella di SQL Server?
- 30. Come eliminare tutte le tabelle da un database in SQL Server 2005 in una dichiarazione tranne una tabella
È possibile aggiungere alcuni (o tutti) i caratteri riportati di seguito 32 pure, particolarmente importante sarebbe Carriage Return (13), Line Feed (10) e Tab (9). –
Un buon punto aggiunto – Andomar
Ho trovato la tecnica come il modo più affidabile per farlo in SQL-Server. – cusman