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 / 217424
Accepted
James
James
Asked: 2018-09-13 11:35:45 +0800 CST2018-09-13 11:35:45 +0800 CST 2018-09-13 11:35:45 +0800 CST

Por que os nomes dos objetos não podem começar com um número?

  • 772

Por exemplo, se estou criando uma view com um name '4aii', por que o SQL Server se importa que comece com um 4? Eu poderia chamar a mesa Fouraiiou IVaii.

Além disso, o que []faz nos bastidores para permitir que qualquer string seja usada como um nome?

Uma corda é uma corda, amirita?

sql-server identifier
  • 5 5 respostas
  • 13429 Views

5 respostas

  • Voted
  1. mustaccio
    2018-09-13T12:01:38+08:002018-09-13T12:01:38+08:00

    Em primeiro lugar, você precisa distinguir entre números (literais numéricos), strings (literais de string) e identificadores. '4aii'é uma string literal, que pode ser um valor de alguma "coisa", mas não identifica (nome) uma coisa. 4aiiou [4aii]seriam identificadores (se fosse permitido).

    O analisador de consulta precisa entender o significado de um token que está sendo observado. Ao permitir que os nomes comecem com dígitos, você, por extensão, permite que eles consistam exclusivamente em dígitos. Então, dado select 12345 from mytable, como você (e o analisador) saberia se 12345é um literal inteiro ou o nome de uma coluna?

    No entanto, se você permitir que os identificadores comecem apenas com letras (ou caracteres de sublinhado), poderá dizer sem ambiguidade se estiver olhando para um identificador ( abc123) ou uma string literal ( 'abc123') -- o último é colocado entre aspas.

    Colchetes no SQL Server, acentos graves (`) no MySQL e aspas duplas em mecanismos compatíveis com ANSI SQL, significam identificadores, e você os usa quando seus identificadores não podem ser facilmente distinguidos de outros tokens: comece com um dígito, tenha espaços ou outros caracteres especiais neles etc. Portanto, [4aii]ou "4aii"diga claramente ao analisador que está lidando com um identificador.

    Uma pequena demonstração do dbfiddle.

    • 20
  2. Best Answer
    Solomon Rutzky
    2018-09-13T21:32:49+08:002018-09-13T21:32:49+08:00

    Uma corda é uma corda, amirita?

    Sim e Não: uma string é uma string, mas os nomes de objeto/item não são strings. Portanto, embora essa afirmação seja verdadeira, também não é relevante para o comportamento que você está vendo.

    Ignorando o raciocínio conceitual para as regras específicas, a resposta técnica para "por que uma funciona e não a outra" é que o SQL Server segue (com personalização mínima), as diretrizes do Padrão Unicode para identificadores. A documentação do Unicode pode ser encontrada aqui:

    Unicode® Standard Anexo nº 31: IDENTIFICADOR UNICODE E SINTAXE DE PADRÃO

    Identificadores que não estão incluídos em nenhum [...]ou "..."são identificadores "regulares", enquanto aqueles que estão incluídos são identificadores "delimitados". Identificadores regulares são nomes que são válidos em todos os contextos (isto é, estas são as regras para nomear coisas nesta linguagem, software, etc). Identificadores delimitados são todo o resto: nomes que não são válidos e não devem funcionar, no entanto, eles recebem uma isenção se você os envolver em qualquer um desses delimitadores. A maioria dos identificadores pode ser delimitada; é apenasGOTOrótulos e variáveis ​​(incluindo variáveis ​​de tabela) / parâmetros que não podem ser delimitados. A diferença parece ser que os identificadores que existem puramente para uso na linguagem T-SQL (ou seja, não um nome que será armazenado em um arquivo de dados ou arquivo de log como metadados) não podem ser delimitados (tanto quanto você esperaria em qualquer língua).

    Agora, a documentação do SQL Server não está exatamente completa/correta, mas está correta sobre a classificação do que é um caractere "identificador" válido (inicial e contínuo) proveniente do Unicode 3.2. Se você quiser a lista real de regras para identificadores regulares e delimitados, eu os documentei aqui:

    Lista Completamente Completa de Regras para Identificadores T-SQL

    Para ver a pesquisa que comprova a relação entre as categorizações do Unicode 3.2 e o que o SQL Server aceita para identificadores regulares, visite:

    1. O Uni-Code: a busca pela lista verdadeira de caracteres válidos para identificadores regulares T-SQL, parte 1
    2. O Uni-Code: a busca pela lista verdadeira de caracteres válidos para identificadores regulares T-SQL, parte 2

    Abordando as preocupações observadas nos comentários desta resposta:

    1. Sim, mesmo permitindo que identificadores não delimitados comecem com _, #e @ é contabilizado na especificação Unicode. A seção 1.2 aborda as personalizações das regras básicas e ainda fornece quatro exemplos de personalizações: _, #, @e $. Essas 4 personalizações "potenciais" são exatamente as mesmas 4 que o SQL Server usa. Portanto, o SQL Server permite @Variablee #TempTablenão aponta para fora deste documento Unicode como sendo a fonte das regras.
    2. Conforme observado acima, a documentação do SQL Server afirma que as categorizações usadas são da versão 3.2 do banco de dados de caracteres Unicode e estão atualmente na versão 10. Você não pode usar as definições atuais de Ident_* , conforme encontradas no site Unicode, pois indicando caracteres válidos/inválidos. Os caracteres são adicionados a Ident_Starte Ident_Continueem cada nova versão do Padrão Unicode. A única maneira de ver o conjunto correto de caracteres correspondentes a essas propriedades é fazer download do Unicode Versão 3.2.
    3. Ambos os dois pontos acima são tratados nas duas postagens de blog mencionadas diretamente acima (chamadas "O Uni-Code: A busca pela lista verdadeira de caracteres válidos para identificadores regulares T-SQL"). Por favor, leia esses dois posts antes de descartar esta resposta como incorreta. Há muitas nuances por trás do que realmente está acontecendo aqui, que abordo nesses dois posts, mostrando passo a passo como combinar a lista de caracteres válidos.

    TAMBÉM, no que diz respeito à pergunta indicada no título, depende de quão frouxamente você define "número". Ou seja, se você seguir as etapas de pesquisa mostradas nas duas postagens mencionadas diretamente acima, de modo que tenha criado uma tabela para conter o Unicode Character Database v3.2 e algumas propriedades adicionais, poderá obter uma lista de 52 não -letras (principalmente "números") que são caracteres válidos para iniciar um identificador por meio da seguinte consulta:

    SELECT ucd.*
    FROM   [v3-2].UnicodeCharacterDatabase ucd
    WHERE  ucd.[IDStart] = 1
    AND    ucd.[GeneralCategory] NOT LIKE 'L%';
    

    Escolhendo alguns desses personagens para testar, podemos ver que eles realmente funcionam:

    USE [tempdb];
    CREATE TABLE dbo.Ⅳaii ([Col1] INT); -- ROMAN NUMERAL FOUR (U+2163)
    
    CREATE TABLE dbo.ↂaii ([Col1] INT); -- ROMAN NUMERAL TEN THOUSAND (U+2182)
    
    CREATE TABLE dbo.〤aii ([Col1] INT); -- HANGZHOU NUMERAL FOUR (U+3024)
    

    E, apenas para mostrar que eles são "números" em mais do que apenas seus nomes, a consulta a seguir prova que eles recebem um valor numérico (conforme mostrado na NumericValuecoluna da [v3-2].UnicodeCharacterDatabasetabela:

    SELECT 1 WHERE N'〤' LIKE N'[3-5]'; -- HANGZHOU NUMERAL FOUR (U+3024)
    -- 1
    

    No entanto, eles não são números que podem ser usados ​​em operações numéricas:

    SELECT 〤 + 0;
    /*
    Msg 207, Level 16, State 1, Line 23
    Invalid column name '〤'.
    */
    

    Em relação à questão da análise e da necessidade de determinar se 3e2é um número ou identificador: embora isso seja uma consideração, e possivelmente por que os números são excluídos da categoria geral Unicode "Ident_start", não é um universal, e não necessariamente por que O SQL Server os exclui. Três pontos a considerar:

    1. Embora 3e2por si só seja ambíguo, se fosse qualificado com pelo menos um nome de esquema, não seria:dbo.3e2
    2. O nome 4aiinão é realmente ambíguo. A análise interna seria capaz de identificar isso facilmente como não sendo um número potencial
    3. MySQL / MariaDB não tem essa restrição. Eles permitem identificadores não delimitados como 4aiie 3e, mas não 3e2ou 300. Consegui executar com sucesso o seguinte no MySQL:

      create table 4aii (3e int);
      

    Então, novamente, o motivo pelo qual você não pode fazer isso no SQL Server é porque o SQL Server adere à recomendação do Unicode Standard para identificadores. Por que esses caracteres foram escolhidos pelo Unicode Consortium não é especificamente declarado, mas parece ser pelo menos "melhor prática". Ainda assim, como comprovado com o MySQL, é possível analisar identificadores que começam com um número.

    • 17
  3. Evan Carroll
    2018-09-13T13:55:41+08:002018-09-13T13:55:41+08:00

    O que você está observando são as regras do lexer da implementação. É parte de um processo chamado análise léxica, que é uma maneira elegante de dizer "dar sentido às coisas". Idealmente, isso seguiria as regras fornecidas no SQL Spec ( <identifier>). Essas regras são todas publicadas pela Microsoft como Regras para Identificadores Regulares . Se você deseja usar identificadores irregulares, você deve citá-los ou "delimitá-los" de outros tokens (Tsql's []ou aspas duplas "") o que elimina qualquer possibilidade de sintaxe ambígua.

    Uma corda é uma corda, amirita?

    Não, tome por exemplo isso.

    "Não, tome por exemplo isso."

    Essa é uma frase. Mas, mais importante, são 5 palavras. Você sabe que são cinco palavras porque o espaço em branco é significativo. Você terá que saber que são cinco palavras se quiser analisar os assuntos, objetos e voz para entender isso como uma instrução.

    • 14
  4. Shadow
    2018-09-13T19:20:01+08:002018-09-13T19:20:01+08:00

    Um exemplo rápido,

    3e2
    

    Essa é a string "3e2"? O número 300? Um nome de variável? E se você quis dizer o número e esqueceu que escreveu 3e2 = 500anteriormente em seu script?

    A regra existe para que um analisador de sintaxe possa entender o que você quer dizer. Pode haver exemplos não ambíguos, 4aiicomo os mencionados em suas perguntas, mas há um subconjunto de rótulos ambíguos. Então, para evitar essa ambiguidade, temos essa regra.

    • 7
  5. david
    2019-12-09T17:32:07+08:002019-12-09T17:32:07+08:00

    Não tive problemas nos últimos 20 anos com uma visão chamada

     530_all
    

    ... mas então eu tive o diabo de um tempo escrevendo um script osql para descartar essa visão (e outras semelhantes) do servidor (SQL Server 2000):

    exec( 'DROP VIEW ' + @ONAME )
    

    DROP VIEW não funcionaria a menos que esses nomes fossem citados.

    E havia, como sempre, algumas restrições misteriosas sobre o uso de concatenação de strings e EXEC e QUOTENAME.

    Se suas ferramentas não permitirem que você crie um nome de objeto como esse... seja grato por pequenas misericórdias.

    • 1

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