Is there a way to make a TSQL variable constant?

前端 未结 12 1041
别那么骄傲
别那么骄傲 2021-02-01 11:31

Is there a way to make a TSQL variable constant?

相关标签:
12条回答
  • 2021-02-01 12:16

    Since there is no build in support for constants, my solution is very simple.

    Since this is not supported:

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

    I would simply convert it to

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

    Obviously, this relies on the whole thing (the value without trailing space and the comment) to be unique. Changing it is possible with a global search and replace.

    0 讨论(0)
  • 2021-02-01 12:18

    There are no such thing as "creating a constant" in database literature. Constants exist as they are and often called values. One can declare a variable and assign a value (constant) to it. From a scholastic view:

    DECLARE @two INT
    SET @two = 2
    

    Here @two is a variable and 2 is a value/constant.

    0 讨论(0)
  • 2021-02-01 12:19

    Prior to using a SQL function run the following script to see the differences in performance:

    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
    
    0 讨论(0)
  • 2021-02-01 12:20

    No, but good old naming conventions should be used.

    declare @MY_VALUE as int
    
    0 讨论(0)
  • 2021-02-01 12:23

    One solution, offered by Jared Ko is to use pseudo-constants.

    As explained in SQL Server: Variables, Parameters or Literals? Or… Constants?:

    Pseudo-Constants are not variables or parameters. Instead, they're simply views with one row, and enough columns to support your constants. With these simple rules, the SQL Engine completely ignores the value of the view but still builds an execution plan based on its value. The execution plan doesn't even show a join to the view!

    Create like this:

    CREATE SCHEMA ShipMethod
    GO
    -- Each view can only have one row.
    -- Create one column for each desired constant.
    -- Each column is restricted to a single value.
    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]
    

    Then use like this:

    SELECT h.*
    FROM Sales.SalesOrderHeader h
    JOIN ShipMethod.ShipMethodID const
        ON h.ShipMethodID = const.[OVERNIGHT J-FAST]
    

    Or like this:

    SELECT h.*
    FROM Sales.SalesOrderHeader h
    WHERE h.ShipMethodID = (SELECT TOP 1 [OVERNIGHT J-FAST] FROM ShipMethod.ShipMethodID)
    
    0 讨论(0)
  • 2021-02-01 12:24

    If you are interested in getting optimal execution plan for a value in the variable you can use a dynamic sql code. It makes the variable constant.

    DECLARE @var varchar(100) = 'some text'
    DECLARE @sql varchar(MAX)
    SET @sql = 'SELECT * FROM table WHERE col = '''+@var+''''
    EXEC (@sql)
    
    0 讨论(0)
提交回复
热议问题