variable stored into columns sql-server tsql

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!