2008-08-25 31 views

cevap

45

Hayır, ancak bir işlev oluşturabilir ve orada kod yazabilir ve bunu kullanabilirsiniz. İşte

bir örnek:

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

SELECT dbo.fnConstant() 
+6

'SCHEMABINDING WITH ** ile ** bunu 'gerçek' bir sabite dönüştürmeliyiz (SQL'de deterministik olarak UDF'nin görülmesi gerekliliği). Yani önbelleğe alınmak zorunda kalmalı. Yine de, +1. –

0

veritabanı literatüründe "sabit yaratma" diye bir şey yoktur. Sabitler, oldukları gibi bulunur ve sıklıkla değer olarak adlandırılır. Bir değişken bildirebilir ve ona bir değer (sabit) atayabilir. Skolastik görünümünden:

DECLARE @two INT 
SET @two = 2 

Burada @ two bir değişkendir ve 2 bir değer/sabittir.

+0

Michal D. ve John Nilsson'un bir performans artışı için cevaplarını da deneyin. –

7

Hayır, ama iyi eski adlandırma kuralları kullanılmalıdır.

declare @MY_VALUE as int 
+0

Eh, gerçekten yaşlı. Neden iyi olduğunu düşünüyorsun? –

+0

@VictorYarema, çünkü bazen kongre ihtiyacınız olan her şeydir. Ve bazen başka iyi bir seçimin olmadığından. Şimdi, bir yana, SQLMenace'ın cevabı daha iyi görünüyor, seninle aynı fikirdeyim. Yine de, işlev adı sabitler için IMO kurallarına uymalıdır. FN_CONSTANT() 'olarak adlandırılmalıdır. Bu şekilde ne yaptığını açık. – tfrascaroli

+0

Bu, yalnızca performans avantajını istediğinizde yardımcı olmaz. Michal D. ve John Nilsson'un performans artışı için cevaplarını da deneyin. –

1

Tamam, bakalım

Sabitler derleme zamanında bilinir ve SQL Server sabit asla anlamına gelir programında

ömrü boyunca değişmeyen sabit değerlerdir

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

değeri sadece

7

diye bir şey yok değişti T-SQL'de sabitler için yerleşik destek. Bunu simüle etmek için SQLMenace'ın yaklaşımını kullanabilirsiniz (bir başkasının başka bir şeye geri dönmek için başka bir işlevin üzerine yazıp yazamayacağından asla emin olamazsınız…), ya da olasılıkla as suggested over here sabitleri içeren bir tablo yazabilirsiniz. Belki de tüm değişiklikleri ConstantValue sütununa geri döndüren bir tetikleyici yazabilir misiniz?

13

eksik Konstans My geçici çözüm optimizer için değeri hakkında ipuçları vermektir.

DECLARE @Constant INT = 123; 

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

Bu yürütme planı oluştururken bunun sürekli sanki değişkeni tedavi etmek sorgu derleyici söyler. Aşağı tarafı, değeri iki kez tanımlamanız gerektiğidir. birden fazla GO ifadeleri/toplu genelinde komut içinde kullanılmak yani için geçici sabit oluşturmak ise

-1

iyi yanıtı ihtiyacına göre SQLMenace arasındadır.

Tam o hedef veritabanında bir etkisi tempdb yordamı oluşturun. Bu

pratik bir örnek mantıksal şema sürümü içeren komut dosyası, sonunda bir kontrol değeri yazar bir veri tabanı oluşturmak komut dosyası. Dosyanın üst kısmında değişiklik geçmişi vb. Bazı yorumlar var. Ancak pratikte çoğu geliştirici, dosyanın alt kısmındaki şema sürümünü aşağı kaydırmayı ve güncellemeyi unutacak. Yukarıdaki kodu kullanarak

görünür bir şema sürümü sabiti (SSMS özelliği oluşturmak komut kopyalanmış) veritabanı komut dosyası önce üst kısmında tanımlanmış bir veritabanı oluşturur ama sonunda kullanılmasını sağlar. Bu, geliştiricinin karşısında değişiklik geçmişinin ve diğer yorumların yanında doğrudur, dolayısıyla güncellemeleri çok olasıdır.Örneğin

:

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 
5

SQL fonksiyonu performans farklılıklarını görmek için aşağıdaki komut dosyasını çalıştırın kullanmadan önce:

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 
+2

Bu oldukça eski, ancak başvuru için burada sunucumda yürütüldüğünde sonuç: | '2760 ms işlevi kullanılarak geçti | Yerel değişkeni kullanarak '2300 ms; Sabit kodlanmış değerleri kullanarak '2286ms geçen, | – z00l

+0

Devasa bir dizüstü bilgisayarda, şema ciltleme olmaksızın iki ek işlevle. '' '5570 işlevi kullanılarak' '' | '' 406, yerel değişkeni kullanarak 'dır | "383, kodlanmış değerleri kullanarak geçti" | '' '' 3893 üst seçmek Karşılaştırma için schemabinding''' – user1778606

+0

olmadan çalışmasını, basit bir seçme ifadesi seçme tablolar '' arasında gidip 4110ms aldı kullanılarak geçen 1 .m = cv_val code_values ​​gelen burada cv_id = 'C101' ' ve aynı '' '... 'C201'' 'Burada code_values ​​250 vars ile sözlük tablosu, tüm SQL-Server 2016 – user1778606

12

Kullanım sözde sabitleri: http://blogs.msdn.com/b/sql_server_appendix_z/archive/2013/09/16/sql-server-variables-parameters-or-literals-or-constants.aspx

Sözde-Sabitler değişkenler veya parametreler değildir. Bunun yerine, , sadece bir satır ve sabitlerinizi desteklemek için yeterli sütunlardır. Bu basit kurallarla, SQL Engine, görünümünün değerini tamamen yok sayar ancak yine de değerine dayanarak bir yürütme planı oluşturur. İcra planı bile görüşe katılmıyor!

4

Eğer dinamik sql kodu kullanabilirsiniz değişkendeki bir değer için optimal yürütme planı almak istiyorsanız. Değişkeni sabit yapar.

çeteleler veya basit sabitleri için
DECLARE @var varchar(100) = 'some text' 
DECLARE @sql varchar(MAX) 
SET @sql = 'SELECT * FROM table WHERE col = '''[email protected]+'''' 
EXEC (@sql) 
+1

vardı Bu nasıl yaptığım ve sabitleri içeren sorgular için büyük bir performans artışı verir . –

1

, tek satır bulunan bir görünümün büyük bir performansa sahiptir ve (onun nedeni sütun adı)

Bkz Jared Ko'nun blog yazısı https://blogs.msdn.microsoft.com/sql_server_appendix_z/2013/09/16/sql-server-variables-parameters-or-literals-or-constants/

/bağımlılık izleme denetleme derleme süresi

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] 

kullanım görünüm görünüm oluşturmak

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

Sabitler için destek oluşturmadığından çözümüm çok basit. Bu yana

desteklenmez:

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

Sadece Açıkçası

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

dönüştürmek istiyorum, bunun için (uzay ve yorumunu sondaki olmadan değer) her şey dayanır benzersiz. Küresel bir arama ile değiştirmek ve değiştirmek mümkündür.

İlgili konular