टीएसक्यूएल वेरिएबल को स्थिर बनाने का कोई तरीका है?
टीएसक्यूएल वेरिएबल को स्थिर बनाने का कोई तरीका है?
जवाबों:
नहीं, लेकिन आप एक फंक्शन बना सकते हैं और इसे वहां पर हार्डकोड कर सकते हैं और इसका उपयोग कर सकते हैं।
यहाँ एक उदाहरण है:
CREATE FUNCTION fnConstant()
RETURNS INT
AS
BEGIN
RETURN 2
END
GO
SELECT dbo.fnConstant()
WITH SCHEMABINDINGमें उपयोग करने के लिए है CREATE FUNCTION(जैसा कि संग्रहित प्रक्रिया में विरोध किया जा सकता है जो फ़ंक्शन को कॉल कर सकता है) - क्या यह सही है?
जेरेड को द्वारा प्रस्तुत एक समाधान, छद्म स्थिरांक का उपयोग करना है ।
एसक्यूएल सर्वर में बताया गया है : चर, पैरामीटर या साहित्य? या… लगातार? :
छद्म-स्थिरांक चर या पैरामीटर नहीं हैं। इसके बजाय, वे केवल एक पंक्ति के साथ विचार कर रहे हैं, और आपके स्थिरांक का समर्थन करने के लिए पर्याप्त कॉलम। इन सरल नियमों के साथ, SQL इंजन दृश्य के मूल्य को पूरी तरह से अनदेखा करता है, लेकिन फिर भी इसके मूल्य के आधार पर एक निष्पादन योजना बनाता है। निष्पादन योजना भी दृश्य में शामिल नहीं होती है!
इस तरह बनाएं:
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]तो इस तरह का उपयोग करें:
SELECT h.* FROM Sales.SalesOrderHeader h JOIN ShipMethod.ShipMethodID const ON h.ShipMethodID = const.[OVERNIGHT J-FAST]या इस तरह:
SELECT h.* FROM Sales.SalesOrderHeader h WHERE h.ShipMethodID = (SELECT TOP 1 [OVERNIGHT J-FAST] FROM ShipMethod.ShipMethodID)
लापता स्थिरांक के लिए मेरा काम है, आशावादी को मूल्य के बारे में संकेत देना।
DECLARE @Constant INT = 123;
SELECT *
FROM [some_relation]
WHERE [some_attribute] = @Constant
OPTION( OPTIMIZE FOR (@Constant = 123))
यह क्वेरी कंपाइलर को चर का इलाज करने के लिए कहता है जैसे कि निष्पादन योजना बनाते समय यह एक स्थिर था। नीचे की ओर यह है कि आपको दो बार मान को परिभाषित करना होगा।
नहीं, लेकिन अच्छे पुराने नामकरण सम्मेलनों का उपयोग किया जाना चाहिए।
declare @MY_VALUE as int
FN_CONSTANT()। इस तरह यह स्पष्ट है कि यह क्या कर रहा है।
टी-एसक्यूएल में स्थिरांक के लिए कोई अंतर्निहित समर्थन नहीं है। आप इसे अनुकरण करने के लिए 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
2760ms elapsed, using function| 2300ms elapsed, using local variable| 2286ms elapsed, using hard coded values|
5570 elapsed, using function | 406 elapsed, using local variable| 383 elapsed, using hard coded values| 3893 elapsed, using function without schemabinding
select top 1 @m = cv_val from code_values where cv_id = 'C101' और ... 'C201' जहाँ कोड_वल्यूस 250 संस्करण के साथ डिक्शनरी टेबल है, SQL Server-2016 पर सभी थे
यदि आप चर में एक मूल्य के लिए इष्टतम निष्पादन योजना प्राप्त करने में रुचि रखते हैं, तो आप एक गतिशील sql कोड का उपयोग कर सकते हैं। यह चर को स्थिर बनाता है।
DECLARE @var varchar(100) = 'some text'
DECLARE @sql varchar(MAX)
SET @sql = 'SELECT * FROM table WHERE col = '''+@var+''''
EXEC (@sql)
Enums या सरल स्थिरांक के लिए, एक पंक्ति के साथ एक दृश्य में बहुत अच्छा प्रदर्शन होता है और समय की जाँच / निर्भरता ट्रैकिंग (इसके स्तंभ पर कारण) का संकलन होता है
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 )
चूंकि स्थिरांक के समर्थन में कोई निर्माण नहीं है, इसलिए मेरा समाधान बहुत सरल है।
चूंकि यह समर्थित नहीं है:
Declare Constant @supplement int = 240
SELECT price + @supplement
FROM what_does_it_cost
मैं बस इसे परिवर्तित कर दूंगा
SELECT price + 240/*CONSTANT:supplement*/
FROM what_does_it_cost
जाहिर है, यह पूरी बात पर निर्भर करता है (अंतरिक्ष और टिप्पणी के बिना पीछे मूल्य) अद्वितीय होने के लिए। इसे बदलना वैश्विक खोज और प्रतिस्थापन के साथ संभव है।
डेटाबेस साहित्य में "एक स्थिर बनाने" जैसी कोई चीज नहीं है। स्थिरांक के रूप में वे मौजूद हैं और जिन्हें अक्सर मूल्य कहा जाता है। कोई एक चर घोषित कर सकता है और इसे एक मान (स्थिर) दे सकता है। एक विद्वान दृष्टिकोण से:
DECLARE @two INT
SET @two = 2
यहाँ @two एक चर है और 2 एक मान / स्थिरांक है।
2को "संकलन समय" में असाइन किए जाने पर एक द्विआधारी मूल्य में अनुवादित किया जाता है। एन्कोड किया गया वास्तविक मान उस डेटा प्रकार पर निर्भर करता है जिसे उसे (int, char, ...) को सौंपा जा रहा है।
सबसे अच्छा उत्तर SQLMenace से है आवश्यकता के अनुसार यदि स्क्रिप्ट के भीतर उपयोग के लिए एक अस्थायी स्थिरांक बनाना है, अर्थात कई GO स्टेटमेंट्स / बैचों में।
बस 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
WITH SCHEMABINDINGइसे 'वास्तविक' स्थिरांक में बदलना चाहिए (यूडीएफ के लिए एक आवश्यकता को SQL में निर्धारक के रूप में देखा जाना चाहिए)। यानी इसे कैश किया जाना चाहिए। फिर भी, +1।