¿Hay alguna manera de hacer que una variable TSQL sea constante?¿Hay alguna manera de hacer que una variable TSQL sea constante?
Respuesta
No, pero puede crear una función y codificarla allí y usarla.
Aquí se muestra un ejemplo:
CREATE FUNCTION fnConstant()
RETURNS INT
AS
BEGIN
RETURN 2
END
GO
SELECT dbo.fnConstant()
No existe la "creación de 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 vista escolástica:
DECLARE @two INT
SET @two = 2
Aquí @two es una variable y 2 es un valor/constante.
Pruebe las respuestas de Michal D. y John Nilsson para un aumento en el rendimiento también. –
No, pero los buenos viejos convenciones de nomenclatura se debe utilizar.
declare @MY_VALUE as int
Bueno, es realmente viejo. ¿Por qué piensas que es bueno? –
@VictorYarema porque a veces la convención es todo lo que necesita. Y porque a veces no tienes otra opción buena. Ahora, aparte de eso, la respuesta de SQLMenace se ve mejor, estaré de acuerdo contigo. Aun así, el nombre de las funciones debe seguir la convención para constantes, IMO. Debería llamarse 'FN_CONSTANT()'. De esa forma está claro lo que está haciendo. – tfrascaroli
Esto solo no ayudará cuando desee el beneficio de rendimiento. Pruebe las respuestas de Michal D. y John Nilsson para mejorar el rendimiento también. –
Está bien, vamos a ver
Las constantes son valores inmutables que son conocidos en tiempo de compilación y no cambian durante la vida del programa
que significa que nunca 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
no hay soporte integrado para 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, as suggested over here. ¿Quizás escriba un activador que revierte los cambios a la columna ConstantValue
?
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.
La mejor respuesta es de SQLMenace según 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 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 el script de base de datos (copiado de la característica de generación de scripts de SSMS) crea la base de datos pero se usa 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
Antes de utilizar 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
Esto es bastante antiguo, pero para referencia aquí está el resultado cuando se ejecuta en mi servidor: | '2760ms transcurridos, usando la función' | '2300ms transcurridos, utilizando la variable local' | '2286ms transcurridos, utilizando valores codificados de forma rígida' | – z00l
En una computadora portátil dev, con dos funciones adicionales sin enlace de esquema. '' '5570 transcurrido, usando la función' '' | '' '406 transcurrido, usando la variable local''' | '' '383 transcurrido, utilizando valores codificados''' | '' '3893 transcurrido, usando la función sin schemabinding''' – user1778606
Para comparación, una instrucción de selección simple tomó 4110ms donde las instrucciones de selección alternaron entre' '' seleccionar top 1 @m = cv_val de code_values donde cv_id = 'C101' '' ' y el mismo '' '... 'C201'' '' donde code_values es una tabla de diccionario con 250 vars, había todo en SQL-Server 2016 – user1778606
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
Las pseudoconstantes no son variables o parámetros. En su lugar, son simples vistas con una fila y suficientes columnas para admitir 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!
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 = '''[email protected]+''''
EXEC (@sql)
Así es como lo hago y ofrece un gran impulso al rendimiento para las consultas que involucran constantes . –
Para enumeraciones o constantes simples, una vista con una sola fila tiene un gran rendimiento y tiempo de compilación comprobación/dependencia de seguimiento (causa de su nombre de una columna)
el blog de Ver Jared Ko https://blogs.msdn.microsoft.com/sql_server_appendix_z/2013/09/16/sql-server-variables-parameters-or-literals-or-constants/
crear 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]
uso de la vista
SELECT h.*
FROM Sales.SalesOrderHeader h
JOIN ShipMethod.ShipMethodID const
ON h.ShipMethodID = const.[OVERNIGHT J-FAST]
Dado que no existe una construcción en soporte de constantes, mi solución es muy simple.
Dado que esto no es compatible:
Declare Constant @supplement int = 240
SELECT price + @supplement
FROM what_does_it_cost
simplemente sería convertirlo en
SELECT price + 240/*CONSTANT:supplement*/
FROM what_does_it_cost
Obviamente, esto depende de todo el asunto (el valor sin arrastrando el espacio y el comentario) para ser único. Cambiarlo es posible con una búsqueda y reemplazo global.
- 1. ¿Hay alguna manera de hacer que un operador de comparación sea una variable?
- 2. ¿Hay alguna manera fácil de hacer que ScrollViewer sea "hinchable"?
- 3. ¿Hay alguna manera de hacer que UserControl sea inafocable?
- 4. ¿Hay alguna manera de hacer que el widget de texto Tkinter sea solo de lectura?
- 5. ¿Hay alguna manera de hacer que la salida de PrintWriter sea en formato UNIX?
- 6. ¿Hay alguna manera de hacer que el proceso de doxigen código C no documentado sea automático?
- 7. ¿Hay alguna manera de hacer la asignación de servlets en eclipse IDE que no sea manualmente?
- 8. ¿Hay alguna manera de hacer que el simulador de iPad sea más grande?
- 9. ¿Hay alguna manera de hacer que un DIV no sea seleccionable?
- 10. ¿Hay alguna manera de hacer que @section sea opcional con asp.net mvc Razor ViewEngine?
- 11. ¿Hay alguna manera fácil de hacer que la matriz anidada sea plana?
- 12. ¿Hay alguna manera de hacer que un ExecutorService funcione recursivamente?
- 13. ¿Hay alguna manera de hacer que Guice Grapher trabaje?
- 14. ¿Hay alguna manera de hacer que TFS se pueda enlazar?
- 15. PHP. ¿Hay alguna manera de requerir que un parámetro de función sea una matriz?
- 16. ¿Hay alguna solución para hacer que un miembro de la estructura sea de alguna manera "privado" en C?
- 17. ¿Hay alguna manera de probar una variable para "isForEachable"
- 18. ¿Hay alguna manera de ver cuánta memoria usa una variable?
- 19. ¿Hay alguna forma de recorrer una variable de tabla en TSQL sin usar un cursor?
- 20. ¿Hay alguna manera de hacer una verificación parcial en TFS?
- 21. ¿Hay alguna manera de hacer una función atómica en C? .
- 22. ¿Hay alguna manera de hacer que un constructor solo sea visible para una clase padre en C#?
- 23. ¿Hay alguna manera fácil en Python de esperar hasta que cierta condición sea verdadera?
- 24. ¿Hay alguna manera de declarar una variable que implementa múltiples interfaces en .Net?
- 25. ¿Hay alguna manera de hacer parciales de carga AngularJS al principio y no cuando sea necesario?
- 26. ¿Hay alguna manera de desactivar una etiqueta?
- 27. ¿Hay alguna manera de hacer que un enlace se pueda hacer clic en el terminal OSX?
- 28. ¿Hay alguna manera, usando plantillas, para evitar que una clase sea derivable en C++
- 29. ¿Hay alguna manera de hacer que IE8 no ignore una regla CSS que solo entiende parcialmente?
- 30. ¿Hay alguna manera de hacer que Eclipse ejecute una prueba JUnit varias veces hasta que falle?
'WITH SCHEMABINDING' ** debe ** convertir esto en una constante 'real' (un requisito para que un UDF sea visto como determinista en SQL). Es decir. debería aterrizar en la memoria caché. Aún así, +1. –