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 / 157912
Accepted
gareth
gareth
Asked: 2016-12-13 07:50:04 +0800 CST2016-12-13 07:50:04 +0800 CST 2016-12-13 07:50:04 +0800 CST

Por que não posso usar variáveis ​​em T-SQL como imagino que posso?

  • 772

Perdoe-me, sou um desenvolvedor que mudou para o mundo do SQL. Achei que poderia melhorar um pouco do SQL adicionando variáveis, mas não funcionou como eu esperava. Alguém pode me dizer por que isso não funciona? Não quero uma solução alternativa, quero saber os motivos pelos quais isso não funciona como imagino que deveria, pois tenho certeza de que há um bom motivo, mas atualmente não salta para mim.

DECLARE @DatabaseName varchar(150)
SET @DatabaseName = 'MyAmazingDatabaseName'

CREATE DATABASE @DatabaseName
GO

USE @DatabaseName
GO
sql-server-2008 t-sql
  • 4 4 respostas
  • 4857 Views

4 respostas

  • Voted
  1. Best Answer
    Bob Klimes
    2016-12-13T08:34:37+08:002016-12-13T08:34:37+08:00

    De acordo com a página on-line de livros para variáveis

    As variáveis ​​podem ser usadas apenas em expressões, não no lugar de nomes de objetos ou palavras-chave. Para construir instruções SQL dinâmicas, use EXECUTE.

    Funcionaria da maneira que você esperava se, por exemplo, você usasse sua variável em uma cláusula where. Quanto ao motivo, acho que tem algo a ver com o analisador não ser capaz de avaliar a variável e, assim, verificar a existência. Ao executar, a consulta é analisada primeiro para sintaxe e objetos e, em seguida, se a análise for bem-sucedida, a consulta é executada no ponto em que a variável seria definida.

    DECLARE @name varchar(20);
    SET @name = 'test';
    
    CREATE TABLE [#tmp]([val] varchar(10));
    
    insert into #tmp
    values('test')
    
    SELECT *
    FROM [#tmp]
    WHERE [val] = @name;
    
    • 21
  2. grahamj42
    2016-12-13T10:37:35+08:002016-12-13T10:37:35+08:00

    As limitações no uso de variáveis ​​em instruções SQL surgem da arquitetura do SQL.

    Existem três fases no processamento de uma instrução SQL:

    1. Preparação - A instrução é analisada e um plano de execução é compilado, especificando quais objetos do banco de dados são acessados, como são acessados ​​e como estão relacionados. O plano de execução é salvo no cache do plano .
    2. Vinculação - quaisquer variáveis ​​na instrução são substituídas por valores reais.
    3. Execução - o plano em cache é executado com os valores vinculados.

    O SQL Server esconde a etapa de preparação do programador e a executa muito mais rápido do que os bancos de dados mais tradicionais, como Oracle e DB2. É por motivos de desempenho que o SQL gasta potencialmente muito tempo determinando um plano de execução ideal, mas só o faz na primeira vez que a instrução é encontrada após uma reinicialização.

    Portanto, no SQL estático , as variáveis ​​só podem ser usadas em locais onde não invalidarão o plano de execução, portanto, não para nomes de tabelas, nomes de colunas (incluindo nomes de colunas em condições WHERE), etc.

    O SQL dinâmico existe para os casos em que não é possível contornar as restrições, e o programador sabe que levará um pouco mais de tempo para executar. O SQL dinâmico pode ser vulnerável à injeção de código mal-intencionado, portanto, tome cuidado!

    • 18
  3. BradC
    2016-12-13T10:19:13+08:002016-12-13T10:19:13+08:00

    Como você pode ver, a pergunta "por que" requer um tipo diferente de resposta, incluindo lógica histórica e suposições subjacentes para o idioma, não tenho certeza se posso realmente fazer justiça a isso.

    Este artigo abrangente do SQL MVP Erland Sommarskog tenta fornecer alguma justificativa, juntamente com a mecânica:

    A maldição e as bênçãos do SQL dinâmico :

    Planos de Consulta de Cache

    Cada consulta executada no SQL Server requer um plano de consulta. Quando você executa uma consulta pela primeira vez, o SQL Server cria um plano de consulta para ela – ou, como diz a terminologia – compila a consulta. O SQL Server salva o plano no cache e, na próxima vez que você executar a consulta, o plano será reutilizado.

    Este (e segurança, veja abaixo) é provavelmente o maior motivo.

    O SQL opera sob a premissa de que as consultas não são operações únicas, mas que serão usadas continuamente. Se a tabela (ou o banco de dados!) não for realmente especificada na consulta, não há como gerar e salvar um plano de execução para uso futuro.

    Sim, nem todas as consultas executadas serão reutilizadas, mas essa é a premissa operacional padrão do SQL , portanto, "exceções" devem ser excepcionais.

    Algumas outras razões listadas por Erland (observe que ele está listando explicitamente as vantagens de usar procedimentos armazenados , mas muitas delas também são vantagens de consultas parametrizadas (não dinâmicas)):

    • O sistema de permissão : o mecanismo SQL não pode prever se você tem direitos para executar uma consulta se não conhecer a tabela (ou banco de dados) na qual estará operando. "Cadeias de permissão" usando SQL dinâmico é um pé no saco.
    • Reduzindo o tráfego de rede : passar o nome do procedimento armazenado e alguns valores de parâmetro pela rede é mais curto do que uma instrução de consulta longa.
    • Lógica de encapsulamento : você deve estar familiarizado com as vantagens de encapsular a lógica de outros ambientes de programação.
    • Acompanhando o que é usado : se eu precisar alterar a definição de uma coluna, como posso encontrar todo o código que a chama? Existem procedimentos do sistema para encontrar dependências em um banco de dados SQL, mas somente se o código estiver em procedimentos armazenados.
    • Facilidade de Escrever Código SQL : A verificação da sintaxe ocorre quando você cria ou modifica um procedimento armazenado, portanto, esperamos que menos erros resultem.
    • Resolução de bugs e problemas : um DBA pode rastrear e medir o desempenho de procedimentos armazenados individuais com muito mais facilidade do que o SQL dinâmico em constante mudança.

    Novamente, cada um deles tem uma centena de nuances que não vou abordar aqui.

    • 7
  4. Kin Shah
    2016-12-13T07:55:24+08:002016-12-13T07:55:24+08:00

    Você precisa usar sql dinâmico

    DECLARE @DatabaseName varchar(150) = 'dbamaint'
    declare @sqltext nvarchar(max) = N''
    
    set @sqltext = N'CREATE DATABASE '+quotename(@DatabaseName)+ ';'
    
    print @sqltext 
    
    -- once you are happy .. uncomment below
    --exec sp_executesql @sqltext
    set @sqltext = ''
    set @sqltext = N'use '+quotename(@DatabaseName)+ ';'
    print @sqltext 
    -- once you are happy .. uncomment below
    --exec sp_executesql @sqltext
    

    abaixo está a saída de print .. assim que você descomentar exec sp_executesql @sqltextas instruções serão realmente executadas ...

    CREATE DATABASE [dbamaint];
    use [dbamaint];
    
    • 2

relate perguntas

  • Melhores práticas para conectar bancos de dados que estão em diferentes regiões geográficas

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

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

  • Downgrade do SQL Server 2008 para 2005

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