sql-server - stored - variables @@ sql server
¿Hay alguna manera de hacer que una variable TSQL sea constante? (12)
¿Hay alguna manera de hacer que una variable TSQL sea constante?
Antes de usar una función de SQL, ejecute la siguiente secuencia de comandos para ver las diferencias en el rendimiento:
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
Como no existe una compilación para las constantes, mi solución es muy simple.
Como esto no es compatible:
Declare Constant @supplement int = 240
SELECT price + @supplement
FROM what_does_it_cost
Simplemente lo convertiría en
SELECT price + 240/*CONSTANT:supplement*/
FROM what_does_it_cost
Obviamente, esto depende de que todo (el valor sin espacio y el comentario) sea único. Cambiarlo es posible con una búsqueda y reemplazo global.
De acuerdo, veamos
Las constantes son valores inmutables que se conocen en tiempo de compilación y no cambian durante la vida del programa
eso significa que nunca se puede tener una constante en SQL Server
declare @myvalue as int
set @myvalue = 5
set @myvalue = 10--oops we just changed it
el valor acaba de cambiar
La mejor respuesta es de SQLMenace de acuerdo con el requisito si se trata de crear una constante temporal para su uso dentro de scripts, es decir, a través de múltiples sentencias / lotes GO.
Simplemente cree el procedimiento en tempdb y luego no tendrá ningún impacto en la base de datos de destino.
Un ejemplo práctico de esto es una secuencia de comandos create de base de datos que escribe un valor de control al final de la secuencia de comandos que contiene la versión de esquema lógico. En la parte superior del archivo hay algunos comentarios con historial de cambios, etc. ... Pero en la práctica, la mayoría de los desarrolladores se olvidarán de desplazarse hacia abajo y actualizar la versión del esquema en la parte inferior del archivo.
El uso del código anterior permite definir una constante de versión de esquema visible en la parte superior antes de que la secuencia de comandos de la base de datos (copiada de la característica de generación de scripts de SSMS) cree la base de datos pero se use al final. Esto está justo frente al desarrollador junto al historial de cambios y otros comentarios, por lo que es muy probable que lo actualicen.
Por ejemplo:
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
Mi solución a los constantes faltantes es dar pistas sobre el valor para el optimizador.
DECLARE @Constant INT = 123;
SELECT *
FROM [some_relation]
WHERE [some_attribute] = @Constant
OPTION( OPTIMIZE FOR (@Constant = 123))
Esto le dice al compilador de consultas que trate la variable como si fuera una constante al crear el plan de ejecución. El lado negativo es que debe definir el valor dos veces.
No hay compatibilidad incorporada para las constantes en T-SQL. Puede usar el enfoque de SQLMenace para simularlo (aunque nunca puede estar seguro de si alguien más ha sobreescrito la función para devolver algo más ...), o posiblemente escriba una tabla que contenga constantes, como se sugiere aquí . ¿Quizás escriba un disparador que revierte cualquier cambio en la columna ConstantValue
?
No hay tal cosa como "crear una constante" en la literatura de la base de datos. Las constantes existen tal como están y a menudo se llaman valores. Uno puede declarar una variable y asignarle un valor (constante). Desde una visión escolástica:
DECLARE @two INT
SET @two = 2
Aquí @two es una variable y 2 es un valor / constante.
No, pero las buenas convenciones de nombres deben ser usadas.
declare @MY_VALUE as int
No, pero puede crear una función y codificarla allí y usarla.
Aquí hay un ejemplo:
CREATE FUNCTION fnConstant()
RETURNS INT
AS
BEGIN
RETURN 2
END
GO
SELECT dbo.fnConstant()
Para enumeraciones o constantes simples, una vista con una única fila tiene un gran rendimiento y un seguimiento del tiempo de compilación / seguimiento de la dependencia (porque es un nombre de columna)
Consulte la publicación de blog de Jared Ko https://blogs.msdn.microsoft.com/sql_server_appendix_z/2013/09/16/sql-server-variables-parameters-or-literals-or-constants/
crea la vista
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]
usa la vista
SELECT h.*
FROM Sales.SalesOrderHeader h
JOIN ShipMethod.ShipMethodID const
ON h.ShipMethodID = const.[OVERNIGHT J-FAST]
Si está interesado en obtener un plan de ejecución óptimo para un valor en la variable, puede usar un código sql dinámico. Hace la variable constante.
DECLARE @var varchar(100) = ''some text''
DECLARE @sql varchar(MAX)
SET @sql = ''SELECT * FROM table WHERE col = ''''''+@var+''''''''
EXEC (@sql)
Utilice pseudo-constantes: http://blogs.msdn.com/b/sql_server_appendix_z/archive/2013/09/16/sql-server-variables-parameters-or-literals-or-constants.aspx
Las pseudoconstantes no son variables o parámetros. En cambio, son simplemente vistas con una fila y suficientes columnas para respaldar sus constantes. Con estas reglas simples, SQL Engine ignora por completo el valor de la vista, pero sigue construyendo un plan de ejecución basado en su valor. ¡El plan de ejecución ni siquiera muestra un join a la vista!