টিএসকিউএল ভেরিয়েবলকে ধ্রুবক করার কোনও উপায় আছে কি?


উত্তর:


60

না, তবে আপনি একটি ফাংশন তৈরি করতে এবং এটিতে হার্ডকোড করতে পারেন এবং এটি ব্যবহার করতে পারেন।

এখানে একটি উদাহরণ:

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

SELECT dbo.fnConstant()

13
WITH SCHEMABINDING এটিকে একটি 'রিয়েল' ধ্রুবক হিসাবে রূপান্তর করা উচিত (কোনও ইউডিএফ-এর এসকিউএল-তে ডিস্ট্রিমেন্টিক হিসাবে দেখা প্রয়োজন)। অর্থাৎ এটি ক্যাশে হয়ে অবতরণ করা উচিত। তবুও, +1।
জোনাথন ডিকিনসন

এই উত্তরটি ভাল, কেবল কৌতূহলীয় স্কেলসার্ভারে কলামগুলি টেবিলটিকে ডিফল্ট মান হিসাবে উল্লেখ করতে পারে। আমি এটি কাজ করতে পারিনি
আব বনেট

4
@ জোনাথন ডিকিনসন স্পষ্ট WITH SCHEMABINDINGকরে বলতে গেলে , আপনার পরামর্শটি CREATE FUNCTIONবিবৃতিতে ব্যবহার করা উচিত (কোনও স্টোরড পদ্ধতিতে যে ফাংশনটি ডেকে আনতে পারে তার বিপরীতে) - এটি কি ঠিক?
হলিস্টিক বিকাশকারী

4
হ্যাঁ, ফাংশনে স্কাইমাইন্ডিংয়ের মাধ্যমে এসকিউএলকে "ইনলাইনড টেবিলের মূল্যবান ফাংশনগুলি" ইনলাইন করার অনুমতি দেয় - সুতরাং এটিও এই ফর্মটিতে থাকা দরকার: gist.github.com/jcdickinson/61a38dedb84b35251da301b128535ceb । ক্যোয়ারী বিশ্লেষক SCHEMABINDING বা BEGIN এর সাথে কিছু ছাড়া ইনলাইন করবে না।
জোনাথন ডিকিনসন


28

জারেড কো দ্বারা প্রদত্ত একটি সমাধান হ'ল সিউডো-কনস্ট্যান্ট ব্যবহার করা ।

এসকিউএল সার্ভারে যেমন ব্যাখ্যা করা হয়েছে : চলক, প্যারামিটার বা লিটারাল? বা… ধ্রুবক? :

সিউডো-কনস্ট্যান্টগুলি ভেরিয়েবল বা পরামিতি নয়। পরিবর্তে, এগুলি কেবল এক সারি দিয়ে দেখা হয় এবং আপনার ধ্রুবকগুলিকে সমর্থন করার জন্য পর্যাপ্ত কলাম রয়েছে। এই সাধারণ নিয়মগুলির সাথে, এসকিউএল ইঞ্জিন দৃশ্যের মানটিকে সম্পূর্ণ উপেক্ষা করে তবে তার মানের উপর ভিত্তি করে একটি কার্যকরকরণ পরিকল্পনা তৈরি করে। মৃত্যুদন্ড কার্যকর করার পরিকল্পনায় ভিউতে যোগ দেওয়াও হয় না!

এটি তৈরি করুন:

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)

4
এটি গৃহীত উত্তরের চেয়ে অনেক বেশি ভাল সমাধান। প্রাথমিকভাবে আমরা স্কেলার ফাংশন রুটে নেমে গিয়েছিলাম এবং এর দুর্দান্ত কার্যকারিতা রয়েছে। এই উত্তরটি এবং জ্যারেড কো-র নিবন্ধের উপরের লিঙ্কটির চেয়ে আরও ভাল।
ডেভিড কস্টার

তবে, স্ক্যালার ফাংশনে স্কেমিনেন্ডিংয়ের সাথে যুক্ত করা তার কার্যকারিতাটি উল্লেখযোগ্যভাবে উন্নত করে।
ডেভিড কোস্টার

লিঙ্কটি এখন মারা গেছে।
ম্যাথিউইউ কর্মিয়ার

4
@ ম্যাথিউউকর্মিয়ার: আমি লিঙ্কটি আপডেট করেছি, যদিও মনে হচ্ছে এমএসডিএন পুরাতন ইউআরএল থেকে যাইহোক নতুনটিতে পুনর্নির্দেশ যোগ করেছে।
ইলমারি করোনেন

23

অনুপস্থিত কনস্ট্যান্সের কাছে আমার কাজটি হ'ল অপটিমাইজারকে মানটি সম্পর্কে ইঙ্গিত দেওয়া।

DECLARE @Constant INT = 123;

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

এটি কোয়েরি সংকলকটিকে ভেরিয়েবলের সাথে চিকিত্সা করতে বলছে যেমন এক্সিকিউশন প্ল্যান তৈরির সময় এটি একটি ধ্রুবক ছিল। নীচের দিকটি হ'ল আপনাকে দুবার মান নির্ধারণ করতে হবে।


4
এটি সহায়তা করে কিন্তু এটি একটি একক সংজ্ঞার উদ্দেশ্যকেও পরাস্ত করে।
মাইকজেআরমেসি 5

10

না, তবে ভাল পুরানো নামকরণের কনভেনশনগুলি ব্যবহার করা উচিত।

declare @MY_VALUE as int

@ ভিক্টর ইয়ারেমা কারণ কখনও কখনও আপনার প্রয়োজন মতো কনভেনশন হয়। এবং কারণ কখনও কখনও আপনার অন্য কোনও ভাল পছন্দ থাকে না। এখন, সেই দিকে, এসকিউএল মেনেসের উত্তরটি আরও ভাল দেখাচ্ছে, আমি আপনার সাথে একমত হব। তবুও, ফাংশনগুলির নামটি কনস্ট্যান্ট, আইএমওর জন্য কনভেনশনটি অনুসরণ করা উচিত। এটি নামকরণ করা উচিত FN_CONSTANT()। এটি কী করছে তা স্পষ্ট।
tfrascaroli

আপনি যখন পারফরম্যান্স সুবিধা চান তখন এটি একা সাহায্য করবে না। পারফরম্যান্স বৃদ্ধির জন্য মাইকেল ডি এবং জন নিলসনের উত্তরগুলি চেষ্টা করে দেখুন।
ওয়ান্ডার ওয়ার্কার

8

টি-এসকিউএল-এ ধ্রুবকগুলির জন্য কোনও অন্তর্নির্মিত সমর্থন নেই। আপনি এসকিউএল মেনেসের পদ্ধতির ব্যবহার করে এটি অনুকরণ করতে পারেন (যদিও আপনি কখনই নিশ্চিত হতে পারবেন না যে কেউ অন্য কোনও কিছু ফেরত দেওয়ার জন্য ফাংশনটি ওভাররাইট করেছে কিনা ...), অথবা সম্ভবত এখানে প্রস্তাবিত অনুসারে একটি টেবিল লিখুন । সম্ভবত একটি ট্রিগার লিখুন যা ConstantValueকলামের কোনও পরিবর্তন ফিরিয়ে আনবে?


7

কোনও এসকিউএল ফাংশন ব্যবহার করার আগে পারফরম্যান্সের পার্থক্যগুলি দেখতে নিম্নলিখিত স্ক্রিপ্টটি চালান:

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

4
এটি বেশ পুরানো, তবে রেফারেন্সের জন্য এখানে আমার সার্ভারে মৃত্যুদন্ড কার্যকর করার ফলাফল রয়েছে: | 2760ms elapsed, using function| 2300ms elapsed, using local variable| 2286ms elapsed, using hard coded values|
z00l

4
একটি স্ক্রিন বাঁধাই ছাড়াই দুটি অতিরিক্ত ফাংশন সহ একটি ডেভ ল্যাপটপে। 5570 elapsed, using function | 406 elapsed, using local variable| 383 elapsed, using hard coded values| 3893 elapsed, using function without schemabinding
monkeyhouse

তুলনা করার জন্য, একটি সাধারণ নির্বাচনী বিবৃতিটি ৪১১০ মিমি নিয়েছে যেখানে নির্বাচনের বিবৃতিগুলি পরিবর্তিত হয় select top 1 @m = cv_val from code_values where cv_id = 'C101' এবং একই জায়গায় ... 'C201' যেখানে কোড_ভ্যালুগুলি 250 ওয়ার্স সহ ডিকশনারি টেবিল হয়, এসকিউএল-সার্ভার 2016-এ সমস্ত ছিল
বানরহাউস

6

আপনি যদি ভেরিয়েবলের কোনও মানটির জন্য সর্বোত্তম কার্যনির্বাহী পরিকল্পনা পেতে আগ্রহী হন তবে আপনি একটি গতিশীল এসকিএল কোড ব্যবহার করতে পারেন। এটি পরিবর্তনশীল ধ্রুবক করে তোলে।

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

4
এইভাবেই আমি এটি করি এবং এটি ধ্রুবকগুলিকে জড়িত প্রশ্নের সাথে একটি দুর্দান্ত পারফরম্যান্স উত্সাহ দেয়।
ওয়ান্ডার ওয়ার্কার

5

এনাম বা সাধারণ ধ্রুবকগুলির জন্য, একটি একক সারি সহ একটি দর্শন দুর্দান্ত পারফরম্যান্স এবং সময় পরীক্ষা / নির্ভরতা ট্র্যাকিং সংকলন করে (এর কলামের নাম দেয়)

জারেড কো-এর ব্লগ পোস্টটি https: //blogs.msdn.mic Microsoft.com/sql_server_appendix_z/2013/09/16/sql-server-variables-paraامی-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  )

3

ঠিক আছে, দেখা যাক

ধ্রুবকগুলি অপরিবর্তনীয় মান যা সংকলন সময়ে জ্ঞাত হয় এবং প্রোগ্রামের জীবনের জন্য পরিবর্তন হয় না

তার অর্থ আপনি কখনই এসকিউএল সার্ভারে স্থির থাকতে পারবেন না

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

মান সবেমাত্র পরিবর্তিত হয়েছে


1

যেহেতু ধ্রুবকদের পক্ষে কোনও বিল্ড নেই তাই আমার সমাধানটি খুব সহজ।

যেহেতু এটি সমর্থিত নয়:

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

আমি কেবল এটিকে রূপান্তর করব

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

স্পষ্টতই, এটি সম্পূর্ণরূপে নির্ভর করে (স্থান এবং মন্তব্য ছাড়াই মূল্য) অনন্য হতে। বিশ্বব্যাপী অনুসন্ধান এবং প্রতিস্থাপনের মাধ্যমে এটি পরিবর্তন সম্ভব।


একটি সমস্যা হ'ল এটি কেবল স্থানীয়ভাবে উপলভ্য
বার্নার্ডো ডাল কর্নো

0

ডাটাবেস সাহিত্যে "ধ্রুবক তৈরি করা" বলে কোনও জিনিস নেই। ধ্রুবকগুলির উপস্থিতি যেমন রয়েছে এবং তাদের প্রায়শই মান বলা হয়। কেউ একটি ভেরিয়েবল ঘোষণা করতে পারে এবং এটিকে একটি মান (ধ্রুবক) নির্ধারণ করতে পারে। একটি শিক্ষাগত দর্শন থেকে:

DECLARE @two INT
SET @two = 2

এখানে @ দুটি পরিবর্তনশীল এবং 2 একটি মান / ধ্রুবক।


পারফরম্যান্স বৃদ্ধির জন্য মাইকেল ডি এবং জন নিলসনের উত্তরগুলি চেষ্টা করে দেখুন।
ওয়ান্ডার ওয়ার্কার 16

লিটারাল সংজ্ঞা অনুসারে স্থির থাকে। 2"সংকলনের সময়" নির্ধারিত হলে এসকিআই / ইউনিকোড (সম্পাদকের উপর নির্ভরশীল) অক্ষরটি বাইনারি মান হিসাবে অনুবাদ হয়। এনকোড করা প্রকৃত মান নির্ভর করে যে ডেটা টাইপ করা হচ্ছে তার উপর নির্ভর করে (int, চর, ...)।
সমিস

-1

প্রয়োজন অনুসারে এসকিউএল মেনেস থেকে সর্বোত্তম উত্তর হ'ল যদি স্ক্রিপ্টগুলির মধ্যে ব্যবহারের জন্য অস্থায়ী ধ্রুবক তৈরি করা হয়, যেমন একাধিক জিও স্টেটমেন্ট / ব্যাচ জুড়ে।

টেম্পডিবিতে কেবল প্রক্রিয়া তৈরি করুন তারপরে আপনার লক্ষ্য ডেটাবেজে কোনও প্রভাব পড়বে না।

এর একটি ব্যবহারিক উদাহরণ হ'ল একটি ডাটাবেস তৈরি স্ক্রিপ্ট যা লজিক্যাল স্কিমা সংস্করণ সম্বলিত স্ক্রিপ্টের শেষে একটি নিয়ন্ত্রণ মান লেখায়। ফাইলের শীর্ষে কিছু পরিবর্তনের ইতিহাস ইত্যাদি সহ কিছু মন্তব্য রয়েছে ... তবে অনুশীলনে বেশিরভাগ বিকাশকারী ফাইলের নীচে স্ক্র্যাম সংস্করণটি স্ক্রোল করে আপডেট করতে ভুলে যাবেন।

উপরের কোডটি ব্যবহার করে ডাটাবেস স্ক্রিপ্ট (এসএসএমএসের উত্পন্ন স্ক্রিপ্ট বৈশিষ্ট্য থেকে অনুলিপি করা) ডাটাবেসটি তৈরি করা হলেও শেষে ব্যবহৃত হওয়ার আগে শীর্ষে একটি দৃশ্যমান স্কিমা সংস্করণ স্থির করে দেওয়া যায়। পরিবর্তনের ইতিহাস এবং অন্যান্য মন্তব্যগুলির পাশে এটি বিকাশকের মুখে ঠিক তাই তারা এটি আপডেট করার খুব সম্ভাবনা রয়েছে।

উদাহরণ স্বরূপ:

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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.