AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 139106
Accepted
pix1985
pix1985
Asked: 2016-05-21 03:02:16 +0800 CST2016-05-21 03:02:16 +0800 CST 2016-05-21 03:02:16 +0800 CST

Existe um equivalente T-SQL para pontuação como [0-9] é para números e [az] é para letras?

  • 772

Existe um equivalente T-SQL dos padrões [0-9]e [a-z]que me permitirá extrair valores de uma coluna que contém pontuação?

Por exemplo:

Create Table #Test
(
Value   VarChar(10)
) 
Insert Into #Test
Values ('123a'), ('456b'), ('12ABC'),('AB!23'),('C?D789')

Select      *
From        #Test
Where       Value like '[0-9][0-9][0-9][a-z]'

Isso retornaria valores em que os 3 primeiros caracteres são números entre 0 e 9 e o último caractere será uma letra entre a e z, portanto, retornaria coisas como 123ae 456b, mas não retornaria um valor de 12ABC.

Quero saber se existe um equivalente para pontuação como [0-9]é para números e [a-z]é para letras para que retorne AB!23e C?D789?

Se eu pudesse usar uma expressão regular, poderia usar a expressão ^[a-zA-Z0-9]*$para corresponder a caracteres alfanuméricos em uma string.

Where       Value like '^[a-zA-Z0-9]*$'

Existe um equivalente SQL para isso?

Eu sei que esse tipo de coisa pode ser feito no RegEx, mas preciso disso no T-SQL, não consigo carregar nenhum assemblie personalizado neste servidor, portanto, não posso usar expressões regulares.

A coluna real é varchar(200) . A ordenação é Latin1_General_CI_AS. Estou usando o SQL Server 2012 Standard Edition.

sql-server sql-server-2012
  • 2 2 respostas
  • 11326 Views

2 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2016-05-21T09:09:04+08:002016-05-21T09:09:04+08:00

    A maior dificuldade em chegar a uma solução precisa está em definir exatamente quais caracteres serão incluídos (ou excluídos, conforme a direção que fizer mais sentido para a operação). Significado:

    • Estamos falando de VARCHARdados / ASCII ou dados NVARCHAR/ Unicode? A lista de caracteres de pontuação para dados ASCII depende da página de código que, por sua vez, depende do agrupamento. ( nesta questão estamos lidando com dados ASCII ).
    • Estamos lidando com pesquisas que diferenciam maiúsculas de minúsculas ou não?
    • Para qual agrupamento a coluna está definida? O agrupamento nos informará a página de código e a distinção entre maiúsculas e minúsculas. ( nesta questão que estamos tratandoLatin1_General_CI_AS )
    • o termo "pontuação" significa apenas caracteres de pontuação padrão (por exemplo ., ,, ;, :, etc) ou significa caracteres não alfanuméricos?
    • Os caracteres de espaço em branco estão incluídos?
    • Os personagens de controle estão incluídos?
    • E os símbolos monetários como ¢, £, ¥, etc?
    • E quanto a símbolos como ©e ™?
    • Quais personagens são considerados "alfa"? Os caracteres não ingleses, como Â, É, Ñ, ß, Þestão incluídos?
    • Como esta pergunta lida com teclados do Reino Unido (consulte a discussão para esta pergunta), e quanto ao caractere Æ/ æ?

    Para ajudar a facilitar a clareza em relação ao comportamento esperado, a consulta a seguir mostrará todos os 256 caracteres do conjunto de caracteres Latin1 (ou seja, página de código 1252) e como funcionam as duas variações da solução proposta por @Shaneis . O primeiro campo (rotulado como Latin1_General_CI_AS) mostra a LIKEcláusula conforme proposta por @Shaneis (no momento em que este livro foi escrito) e o segundo campo (rotulado como Latin1_General_100_BIN2) mostra uma modificação em que cancelei o Collation para especificar um binário (ou seja, um Collation terminando em _BIN2; o _BINOs agrupamentos estão obsoletos, portanto, não os use se você tiver acesso às _BIN2versões), o que significava que também precisava adicionar o A-Zintervalo para filtrar letras maiúsculas, pois o agrupamento atual não diferencia maiúsculas de minúsculas:

    ;WITH nums AS
    (
      SELECT TOP (256) (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1) AS [Decimal]
      FROM   [master].[sys].[all_objects]
    )
    SELECT nm.[Decimal],
           CHAR(nm.[Decimal]) AS [Character],
           CASE WHEN CHAR(nm.[Decimal]) LIKE '%[^a-z0-9]%'
                   THEN 'x' ELSE '' END AS [Latin1_General_CI_AS],
           CASE WHEN CHAR(nm.[Decimal]) LIKE '%[^a-z0-9A-Z]%' COLLATE Latin1_General_100_BIN2
                   THEN 'x' ELSE '' END AS [Latin1_General_100_BIN2]
    FROM   nums nm;
    

    ATUALIZAR

    Deve-se mencionar que SE alguém está realmente procurando encontrar caracteres que são classificados como "pontuação" (e não "símbolo de moeda", "símbolo matemático", etc) e SE não está proibido de usar SQLCLR / carregar um arquivo personalizado Assembly (o SQLCLR foi introduzido com o SQL Server 2005 e ainda não encontrei um bom motivo para não permitir isso, especialmente porque o Banco de Dados SQL V12 do Azure oferece suporte a SAFEAssemblies), então você pode usar Expressões Regulares, mas não pelo motivo que a maioria das pessoas iria adivinhar.

    Em vez de usar expressões regulares para criar um intervalo de caracteres mais funcional, ou mesmo em vez de usar algo como \w(significando qualquer caractere de "palavra"), você pode especificar a categoria Unicode dos caracteres que deseja filtrar e existem várias categorias definidas :

    https://www.regular-expressions.info/unicode.html#category

    Você pode até especificar o Bloco Unicode para filtrar, como "InBengali" ou "InDingbats" ou "InOptical_Character_Recognition", etc:

    https://www.regular-expressions.info/unicode.html#block

    Existem vários exemplos de criação de funções RegEx para SQL Server (embora a maioria dos exemplos não siga as práticas recomendadas do SQLCLR), ou você pode baixar a versão gratuita da biblioteca SQL# (que eu criei) e usar a função escalar RegEx_IsMatch da seguinte maneira :

    SQL#.RegEx_IsMatch(Unicode-String-Expression, N'\p{P}', 1, NULL)
    

    A \p{P}expressão significa \p= Categoria Unicode e {P}= todas as pontuações (em oposição a um tipo específico de pontuação, como "Pontuação do Conector"). E a categoria "Pontuação" inclui toda a pontuação em todos os idiomas! Você pode ver a lista completa no site Unicode.org através do seguinte link (existem atualmente 717 Code Points nessa categoria):

    http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AGeneral_Category%3DPunctuation%3A%5D

    Uma versão atualizada da consulta de teste mostrada acima, incluindo outro campo que usa SQL#.RegEx_IsMatch com \p{P}, e os resultados de todos os 3 testes em todos os 256 caracteres da página de código 1252 (ou seja, Latin1_General) foram publicados em PasteBin.com em:

    Consulta T-SQL e resultados para filtrar tipos de caracteres


    ATUALIZAÇÃO
    O seguinte foi mencionado na discussão relacionada:

    Você fez uma boa observação sobre caracteres acentuados, sendo eles nomes de hotéis de todo o mundo, haverá caracteres acentuados nos nomes, para o meu problema, gostaria de classificá-los como caracteres alfa válidos.

    Nesse caso:

    1. Existem 11 caracteres não ingleses incluídos no conjunto de caracteres Latin1/Página de código que não correspondem ao a-zintervalo. São eles: ð Ð Þ þ œ Œ š Š ž Ž Ÿ. Eles precisam ser adicionados ao curinga e, embora não sejam necessários no momento, não faria mal nenhum adicioná-los A-Zpara que o padrão funcione tão bem em um agrupamento com distinção entre maiúsculas e minúsculas. O resultado final é:
      LIKE '%[^a-zA-Z0-9ðÐÞþœŒšŠžŽŸ]%'

    2. Considerando que esses dados podem incluir "nomes de hotéis de todo o mundo", eu recomendo alterar o tipo de dados da coluna para NVARCHARque você possa armazenar todos os caracteres de todos os idiomas. Manter isso como VARCHARcorre um risco muito alto de eventualmente ter perda de dados, pois você só pode representar os idiomas baseados em latim, e nem mesmo totalmente para aqueles que recebem as seis categorias suplementares de Unicode que fornecem caracteres adicionais relacionados ao latim.

    • 12
  2. Shaneis
    2016-05-21T07:29:43+08:002016-05-21T07:29:43+08:00

    Posso estar simplificando demais isso um pouco, mas, se dissermos que a pontuação é tudo o que resta quando os valores alfanuméricos são removidos, o seguinte procurará por strings que contenham caracteres não alfanuméricos.

    Create Table #Test
    (
    Value   VarChar(10)
    ) 
    Insert Into #Test
    Values ('123a'), ('456b'), ('12ABC'),('AB!23'),('C?D789')
    
    -- Original
    Select      *
    From        #Test
    Where       Value like '[0-9][0-9][0-9][a-z]'
    
    -- Non Alpha-numeric
    SELECT * FROM #Test WHERE Value LIKE '%[^a-z0-9]%';
    
    DROP TABLE #Test;
    
    • 5

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve