Existe uma maneira de fazer uma constante variável TSQL?

votos
63

Existe uma maneira de fazer uma constante variável TSQL?

Publicado 25/08/2008 em 18:03
fonte usuário
Em outras línguas...                            


12 respostas

votos
0

Não há tal coisa como "a criação de uma constante" na literatura banco de dados. existem constantes como elas são e muitas vezes chamado de valores. Pode-se declarar uma variável e atribuir um valor (constante) a ele. Do ponto de vista da escola:

DECLARE @two INT
SET @two = 2

Aqui @two é uma variável e 2 é um valor / constante.

Respondeu 25/08/2008 em 18:05
fonte usuário

votos
45

Não, mas você pode criar uma função e codificá-lo lá e usar isso.

Aqui está um exemplo:

CREATE FUNCTION fnConstant()
RETURNS INT
AS
BEGIN
    RETURN 2
END
GO

SELECT dbo.fnConstant()
Respondeu 25/08/2008 em 18:05
fonte usuário

votos
8

Não, mas bons velhos convenções de nomenclatura deve ser usado.

declare @MY_VALUE as int
Respondeu 25/08/2008 em 18:15
fonte usuário

votos
2

Ok, vamos ver

Constantes são valores imutáveis ​​que são conhecidos em tempo de compilação e não mudam durante a vida do programa

que significa que você nunca pode ter uma constante em SQL Server

declare @myvalue as int
set @myvalue = 5
set @myvalue = 10--oops we just changed it

o valor apenas mudou

Respondeu 25/08/2008 em 18:16
fonte usuário

votos
7

Não há nenhum suporte embutido para constantes em T-SQL. Você pode usar a abordagem de SQLMenace para simulá-lo (embora você nunca pode ter certeza se alguém tenha substituído a função para retornar outra coisa ...), ou possivelmente escrever uma tabela contendo constantes, como sugerido por aqui . Talvez escrever um gatilho que reverte quaisquer alterações à ConstantValuecoluna?

Respondeu 25/08/2008 em 18:16
fonte usuário

votos
14

Minha solução para constans falta é dar dicas sobre o valor para o otimizador.

DECLARE @Constant INT = 123;

SELECT * 
FROM [some_relation] 
WHERE [some_attribute] = @Constant
OPTION( OPTIMIZE FOR (@Constant = 123))

Isso informa o compilador de consulta para tratar a variável como se fosse uma constante ao criar o plano de execução. O lado negativo é que você tem que definir o valor duas vezes.

Respondeu 04/10/2012 em 07:31
fonte usuário

votos
-1

A melhor resposta é de SQLMenace acordo com a exigência se isso é criar uma constante temporária para uso dentro de scripts, ou seja, através de múltiplas GO declarações / lotes.

Basta criar o procedimento no tempdb então você não tem impacto sobre o banco de dados alvo.

Um exemplo prático disso é um script de banco de dados criar que escreve um valor de controle no final do script que contém a versão do esquema lógico. No topo do arquivo estão alguns comentários com histórico de alterações etc ... Mas, na prática a maioria dos desenvolvedores se esqueça de rolar para baixo e atualizar a versão do esquema na parte inferior do arquivo.

Usando o código acima permite que uma versão do esquema visível constante a ser definido no topo antes do script de banco de dados (copiado a partir dos scripts geram apresentam de SSMS) cria o banco de dados, mas utilizado no final. Esta é a direita na cara do dono da obra ao lado do histórico de alterações e outros comentários, por isso eles são muito propensos a atualizá-lo.

Por exemplo:

use tempdb
go
create function dbo.MySchemaVersion()
returns int
as
begin
    return 123
end
go

use master
go

-- Big long database create script with multiple batches...
print 'Creating database schema version ' + CAST(tempdb.dbo.MySchemaVersion() as NVARCHAR) + '...'
go
-- ...
go
-- ...
go
use MyDatabase
go

-- Update schema version with constant at end (not normally possible as GO puts
-- local @variables out of scope)
insert MyConfigTable values ('SchemaVersion', tempdb.dbo.MySchemaVersion())
go

-- Clean-up
use tempdb
drop function MySchemaVersion
go
Respondeu 03/12/2012 em 12:56
fonte usuário

votos
6

Antes de usar uma função SQL execute o seguinte script para ver as diferenças de desempenho:

IF OBJECT_ID('fnFalse') IS NOT NULL
DROP FUNCTION fnFalse
GO

IF OBJECT_ID('fnTrue') IS NOT NULL
DROP FUNCTION fnTrue
GO

CREATE FUNCTION fnTrue() RETURNS INT WITH SCHEMABINDING
AS
BEGIN
RETURN 1
END
GO

CREATE FUNCTION fnFalse() RETURNS INT WITH SCHEMABINDING
AS
BEGIN
RETURN ~ dbo.fnTrue()
END
GO

DECLARE @TimeStart DATETIME = GETDATE()
DECLARE @Count INT = 100000
WHILE @Count > 0 BEGIN
SET @Count -= 1

DECLARE @Value BIT
SELECT @Value = dbo.fnTrue()
IF @Value = 1
    SELECT @Value = dbo.fnFalse()
END
DECLARE @TimeEnd DATETIME = GETDATE()
PRINT CAST(DATEDIFF(ms, @TimeStart, @TimeEnd) AS VARCHAR) + ' elapsed, using function'
GO

DECLARE @TimeStart DATETIME = GETDATE()
DECLARE @Count INT = 100000
DECLARE @FALSE AS BIT = 0
DECLARE @TRUE AS BIT = ~ @FALSE

WHILE @Count > 0 BEGIN
SET @Count -= 1

DECLARE @Value BIT
SELECT @Value = @TRUE
IF @Value = 1
    SELECT @Value = @FALSE
END
DECLARE @TimeEnd DATETIME = GETDATE()
PRINT CAST(DATEDIFF(ms, @TimeStart, @TimeEnd) AS VARCHAR) + ' elapsed, using local variable'
GO

DECLARE @TimeStart DATETIME = GETDATE()
DECLARE @Count INT = 100000

WHILE @Count > 0 BEGIN
SET @Count -= 1

DECLARE @Value BIT
SELECT @Value = 1
IF @Value = 1
    SELECT @Value = 0
END
DECLARE @TimeEnd DATETIME = GETDATE()
PRINT CAST(DATEDIFF(ms, @TimeStart, @TimeEnd) AS VARCHAR) + ' elapsed, using hard coded values'
GO
Respondeu 30/12/2012 em 22:40
fonte usuário

votos
13

Use pseudo-constantes: http://blogs.msdn.com/b/sql_server_appendix_z/archive/2013/09/16/sql-server-variables-parameters-or-literals-or-constants.aspx

Pseudo-Constantes não são variáveis ​​ou parâmetros. Em vez disso, eles estão simplesmente pontos de vista com uma linha e colunas suficientes para sustentar suas constantes. Com estas regras simples, o mecanismo SQL ignora completamente o valor da vista, mas ainda constrói um plano de execução com base no seu valor. O plano de execução não mostram mesmo uma junção para a vista!

Respondeu 03/09/2015 em 10:03
fonte usuário

votos
5

Se você estiver interessado em obter o plano de execução ideal para um valor na variável que você pode usar um código SQL dinâmico. Faz a constante variável.

DECLARE @var varchar(100) = 'some text'
DECLARE @sql varchar(MAX)
SET @sql = 'SELECT * FROM table WHERE col = '''+@var+''''
EXEC (@sql)
Respondeu 23/09/2016 em 10:35
fonte usuário

votos
2

Para enums ou constantes simples, uma exibição com uma única linha tem grande desempenho e compilar verificação de tempo / dependência de rastreamento (causar seu um nome da coluna)

Veja o blog post de Jared Ko https://blogs.msdn.microsoft.com/sql_server_appendix_z/2013/09/16/sql-server-variables-parameters-or-literals-or-constants/

criar a exibição

 CREATE VIEW ShipMethod.ShipMethodID AS
 SELECT CAST(1 AS INT) AS [XRQ - TRUCK GROUND]
   ,CAST(2 AS INT) AS [ZY - EXPRESS]
   ,CAST(3 AS INT) AS [OVERSEAS - DELUXE]
  , CAST(4 AS INT) AS [OVERNIGHT J-FAST]
   ,CAST(5 AS INT) AS [CARGO TRANSPORT 5]

usar o ponto de vista

SELECT h.*
FROM Sales.SalesOrderHeader h 
JOIN ShipMethod.ShipMethodID const 
   ON h.ShipMethodID = const.[OVERNIGHT J-FAST]
Respondeu 28/12/2017 em 17:31
fonte usuário

votos
1

Como não há construção de apoio para constantes, minha solução é muito simples.

Uma vez que este não é suportado:

Declare Constant @supplement int = 240
SELECT price + @supplement
FROM   what_does_it_cost

Eu simplesmente convertê-lo para

SELECT price + 240/*CONSTANT:supplement*/
FROM   what_does_it_cost

Obviamente, isso depende de toda a coisa (o valor sem os espaços finais eo comentário) ser único. Mudar é possível com uma pesquisa global e substituir.

Respondeu 29/12/2017 em 14:40
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more