有没有办法让TSQL变量保持不变?
不,但你可以在那里创建一个函数并对其进行硬编码并使用它.
这是一个例子:
CREATE FUNCTION fnConstant() RETURNS INT AS BEGIN RETURN 2 END GO SELECT dbo.fnConstant()
我对缺少常量的解决方法是给优化器提供有关值的提示.
DECLARE @Constant INT = 123; SELECT * FROM [some_relation] WHERE [some_attribute] = @Constant OPTION( OPTIMIZE FOR (@Constant = 123))
这告诉查询编译器在创建执行计划时将变量视为常量.缺点是你必须定义两次值.
使用伪常量:http://blogs.msdn.com/b/sql_server_appendix_z/archive/2013/09/16/sql-server-variables-parameters-or-literals-or-constants.aspx
伪常数不是变量或参数.相反,它们只是一行的视图,以及足够的列来支持您的常量.使用这些简单的规则,SQL引擎完全忽略视图的值,但仍然根据其值构建执行计划.执行计划甚至没有显示视图的连接!
不,但应使用良好的旧命名约定.
declare @MY_VALUE as int
T-SQL中没有对常量的内置支持.您可以使用SQLMenace的方法来模拟它(尽管您永远无法确定其他人是否已覆盖该函数以返回其他内容...),或者可能会编写一个包含常量的表,如此处所示.也许写一个触发器来回滚ConstantValue
列的任何更改?
在使用SQL函数之前,请运行以下脚本以查看性能差异:
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
如果您有兴趣为变量中的值获取最佳执行计划,则可以使用动态sql代码.它使变量保持不变.
DECLARE @var varchar(100) = 'some text' DECLARE @sql varchar(MAX) SET @sql = 'SELECT * FROM table WHERE col = '''+@var+'''' EXEC (@sql)
对于枚举或简单常量,具有单行的视图具有出色的性能和编译时检查/依赖性跟踪(导致其列名)
请参阅Jared Ko的博客文章https://blogs.msdn.microsoft.com/sql_server_appendix_z/2013/09/16/sql-server-variables-parameters-or-literals-or-constants/
创建视图
CREATE VIEW ShipMethods 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]
使用视图
SELECT h.* FROM Sales.SalesOrderHeader WHERE ShipMethodID = ( select [OVERNIGHT J-FAST] from ShipMethods )