Сведения о вопросе

None

20:39, 8th August, 2020

Теги

sql-server   tsql    

Есть ли способ сделать переменную TSQL постоянной?

Просмотров: 500   Ответов: 12

Есть ли способ сделать переменную TSQL постоянной?



  Сведения об ответе

piter

03:57, 27th August, 2020

Нет, но вы можете создать функцию и жестко закодировать ее там и использовать это.

Вот такой пример:

CREATE FUNCTION fnConstant()
RETURNS INT
AS
BEGIN
    RETURN 2
END
GO

SELECT dbo.fnConstant()


  Сведения об ответе

прога

15:37, 8th August, 2020

Мой обходной путь к отсутствующим константам заключается в том, чтобы дать подсказки о значении оптимизатору.

DECLARE @Constant INT = 123;

SELECT * 
FROM [some_relation] 
WHERE [some_attribute] = @Constant
OPTION( OPTIMIZE FOR (@Constant = 123))

Это говорит компилятору запроса, чтобы он обрабатывал переменную, как если бы она была константой при создании плана выполнения. Недостатком является то, что вы должны определить значение дважды.


  Сведения об ответе

+-*/

04:20, 16th August, 2020

Используйте псевдо-константы: http://blogs.msdn.com/b/sql_server_appendix_z/archive/2013/09/16/sql-server-variables-parameters-or-literals-or-constants.aspx

Псевдоконстанты не являются переменными или параметрами. А вместо этого они просто ... просто просмотры с одной строкой и достаточным количеством столбцов для поддержки Вашего константы. С помощью этих простых правил движок SQL полностью игнорирует значение представления, но по-прежнему строит план выполнения на основе его значение. План выполнения даже не показывает соединение с представлением!


  Сведения об ответе

ASER

14:26, 20th August, 2020

Нет, но следует использовать старые добрые соглашения об именовании.

declare @MY_VALUE as int


  Сведения об ответе

COOL

18:09, 8th August, 2020

В T-SQL нет встроенной поддержки констант. Вы можете использовать подход SQLMenace для его моделирования (хотя вы никогда не можете быть уверены, что кто-то другой перезаписал функцию, чтобы вернуть что-то другое...), или, возможно, написать таблицу, содержащую константы, как это предлагается здесь . Может быть, написать триггер, который откатывает любые изменения в столбце ConstantValue ?


  Сведения об ответе

COOL

10:37, 8th August, 2020

Перед использованием функции 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


  Сведения об ответе

dumai

04:15, 2nd August, 2020

Если вы заинтересованы в получении оптимального плана выполнения Для значения переменной, вы можете использовать динамический код sql. Это делает переменную постоянной.

DECLARE @var varchar(100) = 'some text'
DECLARE @sql varchar(MAX)
SET @sql = 'SELECT * FROM table WHERE col = '''+@var+''''
EXEC (@sql)


  Сведения об ответе

VCe znayu

19:57, 29th August, 2020

Для enums или простых констант представление с одной строкой имеет большую производительность и время компиляции проверки / отслеживания зависимостей ( причина его имя столбца )

Смотрите запись в блоге Джареда ко 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  )


  Сведения об ответе

LAST

20:46, 11th August, 2020

Ладно, посмотрим

Константы-это неизменяемые значения, которые известны во время компиляции и не изменяются в течение всего срока службы программы

это означает, что вы никогда не сможете иметь константу в SQL сервере

declare @myvalue as int
set @myvalue = 5
set @myvalue = 10--oops we just changed it

значение просто изменилось


  Сведения об ответе

prince

15:01, 25th August, 2020

Поскольку нет никакой сборки в поддержку констант, мое решение очень простое.

Так как это не поддерживается:

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

Я бы просто превратил его в

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

Очевидно, что это зависит от того, что все это (значение без пространства trailing и комментария) будет уникальным. Изменить его можно с помощью глобального поиска и замены.


  Сведения об ответе

JUST___

21:11, 24th August, 2020

В литературе по базам данных нет такого понятия, как "creating a constant". Константы существуют сами по себе и часто называются значениями. Можно объявить переменную и присвоить ей значение (константу). С точки зрения схоластики:

DECLARE @two INT
SET @two = 2

Здесь @two-это переменная, а 2 - это value/constant.


  Сведения об ответе

SEEYOU

18:45, 17th August, 2020

Лучший ответ-от SQLMenace в соответствии с требованием, если это означает создание временной константы для использования в скриптах, т. е. через несколько GO statements/batches.

Просто создайте процедуру в базе данных tempdb, тогда вы не будете иметь никакого влияния на целевую базу данных.

Одним из практических примеров этого является скрипт создания базы данных, который записывает управляющее значение в конце скрипта, содержащего версию логической схемы. В верхней части файла находятся некоторые комментарии с историей изменений и т.д... Но на практике большинство разработчиков забудут прокрутить вниз и обновить версию схемы в нижней части файла.

Использование приведенного выше кода позволяет определить видимую константу версии схемы в верхней части до того, как сценарий базы данных (скопированный из функции генерировать сценарии SSMS) создаст базу данных, но будет использоваться в конце. Это прямо перед лицом разработчика рядом с историей изменений и другими комментариями, поэтому они с большой вероятностью обновят его.

Например:

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться