“তৈরি করুন অনন্য সূচক” এর “যেখানে” অনুচ্ছেদে “লেন” ফাংশনটি ব্যবহার করুন


12

আমার এই টেবিলটি রয়েছে:

CREATE TABLE Table01 (column01 nvarchar(100));

এবং আমি এই শর্তটি LEN (কলাম01)> = 5 দিয়ে কলাম01 এ একটি অনন্য সূচক তৈরি করতে চাই

আমি চেষ্টা করেছিলাম:

CREATE UNIQUE INDEX UIX_01 ON Table01(column01) WHERE LEN(column01) >= 5;

আমি পেয়েছি:

টেবিলে 'টেবিল01' এ ফিল্টারড সূচক 'UIX_01' এর জন্য কোথাও বিধি।

এবং :

ALTER TABLE Table01 ADD column01_length AS (LEN(column01));
CREATE UNIQUE INDEX UIX_01 ON Table01(column01) WHERE column01_length >= 5;

উত্পাদন:

ফিল্টারড ইনডেক্স 'UIX_01' টেবিল 'টেবিল01' তে তৈরি করা যায় না কারণ ফিল্টার এক্সপ্রেশনে কলাম 'কলাম01_ দৈর্ঘ্য' একটি গণিত কলাম। ফিল্টার এক্সপ্রেশনটি পুনরায় লিখুন যাতে এটিতে এই কলামটি অন্তর্ভুক্ত না হয়।

উত্তর:


15

ফিল্টারড সূচক বিধিনিষেধকে কার্যকর করার একটি পদ্ধতি হ'ল একটি সূচিযুক্ত দর্শন সহ:

CREATE TABLE dbo.Table01 (
  Column01 NVARCHAR(100)
);
GO

CREATE VIEW dbo.vw_Table01_Column01_LenOver5Unique
WITH SCHEMABINDING AS
SELECT Column01
FROM dbo.Table01
WHERE LEN(Column01) >= 5;
GO

CREATE UNIQUE CLUSTERED INDEX cdx
    ON dbo.vw_Table01_Column01_LenOver5Unique(Column01);
GO

INSERT INTO dbo.Table01 VALUES('1'); --success
INSERT INTO dbo.Table01 VALUES('1'); --success
INSERT INTO dbo.Table01 VALUES('55555'); --success
INSERT INTO dbo.Table01 VALUES('55555'); --duplicate key error
GO

সম্পাদনা করুন:

যদি সূচীতে আমার দুটি কলাম থাকে তবে আমি কীভাবে ভিউটি সংজ্ঞায়িত করব? সারণী 01 এ অনন্য ইন্ডেক্স UIX_01 তৈরি করুন (কলাম01, কলাম02) যেখানে লেন (কলাম01)> = 5

সংশ্লেষিত দর্শন পদ্ধতির ভিউ সংজ্ঞা এবং সূচকে অন্যান্য কী কলামগুলি যুক্ত করে একটি সংমিশ্রিত কীটির জন্য বাড়ানো যেতে পারে। একই ফিল্টারটি ভিউ সংজ্ঞাতে প্রয়োগ করা হয় তবে একক কলাম মানের পরিবর্তে সম্মিলিত কী দ্বারা প্রয়োগ করা যোগ্যতার সারিগুলির স্বতন্ত্রতা:

CREATE TABLE dbo.Table01 (
   Column01 NVARCHAR(100)
  ,Column02 NVARCHAR(100)
);
GO

CREATE VIEW dbo.vw_Table01_Column01_LenOver5Unique
WITH SCHEMABINDING AS
SELECT Column01, Column02
FROM dbo.Table01
WHERE LEN(Column01) >= 5;
GO

CREATE UNIQUE CLUSTERED INDEX cdx
    ON dbo.vw_Table01_Column01_LenOver5Unique(Column01, Column02)
GO

INSERT INTO dbo.Table01 VALUES('1','A'); --success
INSERT INTO dbo.Table01 VALUES('1','A'); --success
INSERT INTO dbo.Table01 VALUES('55555','A'); --success
INSERT INTO dbo.Table01 VALUES('55555','B'); --success
INSERT INTO dbo.Table01 VALUES('55555','B'); --duplicate key error
GO

এবং আমি আশা করি এটি আমার মনস্ট্রোসিটির চেয়ে আরও ভাল পারফর্ম করবে।
জেমস অ্যান্ডারসন

@ ড্যান গুজম্যানের কি আমাকে 'স্কাইমাইন্ডিং উইথ' ব্যবহার করা উচিত?
geek

2
@ জালিল হ্যাঁ, SCHEMABINDINGএকটি সূচকিত দর্শনের জন্য প্রয়োজনীয়। এর অর্থ অবশ্যই টেবিল পরিবর্তন করার আগে আপনাকে ভিউটি ড্রপ করতে হবে। এসএসডিটির মতো সরঞ্জামাদি স্বয়ংক্রিয়ভাবে সেই নির্ভরতার যত্ন নেবে।
ড্যান গুজম্যান

যদি সূচীতে আমার দুটি কলাম থাকে তবে আমি কীভাবে ভিউটি সংজ্ঞায়িত করব? সারণী 01 এ অনন্য ইন্ডেক্স UIX_01 তৈরি করুন (কলাম01, কলাম02) যেখানে লেন (কলাম01)> = 5;
geek

@ জলিল, আমি আমার উত্তরে একটি সংমিশ্রিত মূল উদাহরণ যুক্ত করেছি।
ড্যান গুজম্যান

5

ফিল্টারড সূচকগুলির অনেকগুলি সীমাবদ্ধতার মধ্যে এটি অন্য বলে মনে হয়। এটি LIKEব্যবহার WHERE column01 LIKE '_____'করে বাইপাস দেওয়ার চেষ্টাটিও কার্যকর হয় না, একই ত্রুটি বার্তাটি তৈরি করে ( "ভুল যেখানে WHOLE ধারা" " )।

VIEWসমাধানের পাশাপাশি , অন্য উপায় হ'ল গণিত কলামকে একটি নিয়মিত কলামে রূপান্তর করা এবং একটি CHECKসীমাবদ্ধতা যুক্ত করা যাতে এটিতে সর্বদা বৈধ ডেটা থাকে:

CREATE TABLE Table01 (column01 nvarchar(100),
                      column01_length int,
                      CHECK ( column01_length = len(column01)
                              AND column01 IS NOT NULL 
                              AND column01_length IS NOT NULL
                           OR column01 IS NULL 
                              AND column01_length IS NULL )
                     ) ;


CREATE UNIQUE INDEX UIX_01 ON Table01 (column01) WHERE column01_length >= 5 ;

Rextester.comপরীক্ষিত

স্বাভাবিকভাবেই, এর অর্থ হ'ল column01_lengthপ্রতিবার আপনি অঙ্কিত হওয়া column01(সন্নিবেশ এবং আপডেটের ক্ষেত্রে) যথাযথ দৈর্ঘ্যের সাথে স্পষ্টভাবে পপুলেশন করা দরকার । এটি জটিল হতে পারে, কারণ আপনারা এটি নিশ্চিত করে নেওয়া দরকার যে টি-এসকিউএল LEN()ফাংশন যেমন করে তার দৈর্ঘ্য একইভাবে গণনা করা হয় । বিশেষত, পিছনের জায়গাগুলি উপেক্ষা করা দরকার, যা ক্লায়েন্ট অ্যাপ্লিকেশনগুলিতে লেখা বিভিন্ন প্রোগ্রামিং ভাষায় ডিফল্টরূপে দৈর্ঘ্যটি কীভাবে গণনা করা যায় তা অগত্যা নয় the প্রথম স্থানে পার্থক্য সম্পর্কে সচেতন।

কলামটির সঠিক মান সরবরাহ করতে একটি বিকল্প হ'ল INSERT/UPDATEট্রিগার 1 হবে, সুতরাং এটি ক্লায়েন্ট অ্যাপ্লিকেশনগুলিতে গণিত হিসাবে প্রদর্শিত হবে।


1 সীমাবদ্ধতার তুলনায় ট্রিগারগুলিতে যেমন ব্যাখ্যা করা হয়েছে , আপনার এটির জন্য একটি ইনস্টল অফ ট্রিগার ব্যবহার করতে হবে। একটি আফ্রিটার ট্রিগার কেবল কখনও কার্যকর করা হবে না, কারণ অনুপস্থিত দৈর্ঘ্য চেক সীমাবদ্ধতা ব্যর্থ করবে এবং ফলস্বরূপ, ট্রিগারটি চলমান থেকে আটকাবে। ইনস্টল অফ ট্রিগারগুলির অবশ্য নিজস্ব বিধিনিষেধ রয়েছে ( দ্রুত পর্যালোচনার জন্য ডিএমএল ট্রিগার পরিকল্পনার নির্দেশিকা দেখুন )।


1

আমি নিশ্চিত না যে এটি কীভাবে সম্পাদন করবে এবং এটি উপেক্ষা করার জন্য আরও সহজ উপায় হতে পারে তবে আপনি যদি স্বতন্ত্রতা প্রয়োগে আগ্রহী হন তবে আপনার যা প্রয়োজন তা করা উচিত।

CREATE TABLE dbo.Table01 
(
  Column01 NVARCHAR(100)
);
GO

CREATE FUNCTION dbo.ChkUniqueColumn01OverLen5()
RETURNS BIT
AS
BEGIN
DECLARE @Result BIT, @Count BIGINT, @DistinctCount BIGINT

SELECT  @Count = COUNT(Column01),
        @DistinctCount = COUNT(DISTINCT Column01)
FROM    Table01
WHERE   LEN(Column01) >= 5 

SELECT @Result = CASE WHEN @Count = @DistinctCount THEN 1 ELSE 0 END

RETURN @Result

END;
GO

ALTER TABLE dbo.Table01
ADD CONSTRAINT Chk_UniqueColumn01OverLen5
CHECK (dbo.ChkUniqueColumn01OverLen5() = 1);
GO

INSERT dbo.Table01 (Column01)
VALUES (N'123'), (N'1234');
GO

INSERT dbo.Table01 (Column01)
VALUES (N'12345');
GO

INSERT dbo.Table01 (Column01)
VALUES (N'12345'); -- Will fail
GO

INSERT dbo.Table01 (Column01)
VALUES (N'123'); -- Will pass
GO

UPDATE dbo.Table01
SET Column01 = '12345'
WHERE Column01 = '1234' -- Will fail
GO

SELECT * FROM dbo.Table01;
GO

DROP TABLE Table01;
DROP FUNCTION dbo.ChkUniqueColumn01OverLen5;

2
চেক সীমাবদ্ধ বা গণিত কলাম সংজ্ঞাতে একটি স্কেলারের মূল্যবান ফাংশন ব্যবহার করা সারণীতে স্পর্শযুক্ত সমস্ত প্রশ্নের ক্রিয়াকলাপভাবে চালাতে বাধ্য করবে, এমনকি তারা কলামটি উল্লেখ না করে।
এরিক ডার্লিং

2
@sp_BlitzErik Yep এবং এটি এই সমাধান সম্পর্কে সবচেয়ে খারাপ জিনিস নাও হতে পারে :)। আমি এটি দেখতে চাই যে এটি কাজ করবে কিনা, তাই পারফরম্যান্সের সতর্কতা।
জেমস অ্যান্ডারসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.