এসকিউএল সার্ভারের জন্য সংজ্ঞাটির সাথে মেলে না এমন ডেটা দিয়ে PERSISTED কলামগুলি পূরণ করা আইনসম্মত?


16

আমি একটি গণনা কলামে অদ্ভুত মান সম্পর্কে এই প্রশ্ন অনুসরণ করছি PERSISTED। উত্তরটি এই আচরণটি কীভাবে হয়েছিল সে সম্পর্কে কয়েকটি অনুমান করে।

আমি নিম্নলিখিতগুলি জিজ্ঞাসা করছি: এটি কি কোনও সম্পূর্ণ বাগ নয়? করছেন PERSISTEDকলাম কি কখনো এইরকম আচরণ করতে দেয়া?

DECLARE @test TABLE (
    Col1 INT,
    Contains2 AS CASE WHEN 2 IN (Col1) THEN 1 ELSE 0 END PERSISTED) --depends on Col1

INSERT INTO @test (Col1) VALUES
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5))

SELECT * FROM @test --shows impossible data

UPDATE @test SET Col1 = Col1*1 --"fix" the data by rewriting it

SELECT * FROM @test --observe fixed data

/*
Col1    Contains2
2   0
2   0
0   1
4   0
3   0

Col1    Contains2
2   1
2   1
0   0
4   0
3   0
*/

দ্রষ্টব্য, যে ডেটা "অসম্ভব" বলে মনে হচ্ছে কারণ গণিত কলামের মানগুলি এর সংজ্ঞা সাথে মিলছে না।

এটি সুপরিচিত যে প্রশ্নগুলিতে অ-নিরস্তামূলক কাজগুলি অদ্ভুত আচরণ করতে পারে তবে এখানে মনে হয় এটি স্থির গণিত কলামগুলির চুক্তি লঙ্ঘন করে এবং তাই এটি অবৈধ হওয়া উচিত।

এলোমেলো সংখ্যা সন্নিবেশ করানো একটি সঙ্কোচিত দৃশ্য হতে পারে তবে যদি আমরা NEWID()মানগুলি সন্নিবেশ করতাম বা SYSUTCDATETIME()? আমি মনে করি এটি একটি প্রাসঙ্গিক সমস্যা যা সম্ভবত ব্যবহারিকভাবে প্রকাশিত হতে পারে।

উত্তর:


9

এটি অবশ্যই একটি বাগ। col1মানগুলি এলোমেলো সংখ্যার সাথে জড়িত একটি অভিব্যক্তির ফলাফল হিসাবে ঘটেছিল তা সত্য যা সঠিক মান col2বলে মনে হয় তা পরিবর্তন করে না । DBCC CHECKDBএটি স্থায়ী টেবিলের বিরুদ্ধে চালিত হলে একটি ত্রুটি প্রদান করে।

create table test (
    Col1 INT,
    Contains2 AS CASE WHEN 2 IN (Col1) THEN 1 ELSE 0 END PERSISTED);

INSERT INTO test (Col1) VALUES
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5));

DBCC CHECKDB

দেয় (আমার পরীক্ষার জন্য যার "অসম্ভব" সারি ছিল)

Msg 2537, Level 16, State 106, Line 17
Table error: object ID 437576597, index ID 0, partition ID 72057594041008128, alloc unit ID 72057594046251008 (type In-row data), page (1:121), row 0. The record check (valid computed column) failed. The values are 2 and 0.
DBCC results for 'test'.
There are 5 rows in 1 pages for object "test".
CHECKDB found 0 allocation errors and 1 consistency errors in table 'test' (object ID 437576597).

এটি যে রিপোর্ট করে না

DBCC CHECKDB দ্বারা পাওয়া ত্রুটিগুলির জন্য মেরামত_নীল_ডাটা_লাস সর্বনিম্ন মেরামতের স্তর

এবং যদি মেরামত বিকল্পটি গ্রহণ করা হয় তবে নির্বিঘ্নে পুরো সারিটি মুছে ফেলা হয় কারণ এটি বলার উপায় নেই যে কোন কলামটি নষ্ট হয়েছে।

একটি ডিবাগার সংযুক্তি দেখায় যে NEWID()সন্নিবেশ করা সারিতে প্রতিবার দুবার মূল্যায়ন করা হচ্ছে। CASEভাব প্রকাশের আগে একবার এবং এর ভিতরে একবার।

এখানে চিত্র বর্ণনা লিখুন

সম্ভবত একটি সম্ভাব্য কাজ ব্যবহার করা যেতে পারে

INSERT INTO @test
            (Col1)
SELECT ( ABS(CHECKSUM(NEWID()) % 5) )
FROM   (VALUES (1),(1),(1),(1),(1)) V(X); 

যা এক কারণে বা অন্য কোনও কারণে বিষয়টি এড়ানো যায় এবং প্রতি সারিতে একবারে অভিব্যক্তিটি মূল্যায়ন করে।


2

মন্তব্য কথোপকথন অনুযায়ী, sensক্যমত্য বলে মনে হয় যে ওপি-র প্রশ্নের উত্তর হ'ল এটি একটি বাগ গঠন করে (অর্থাত অবৈধ হওয়া উচিত)।

ওপি স্ট্যাকওভারফ্লো সম্পর্কে ভ্লাদিমির বারানভের বিশ্লেষণের উল্লেখ করেছে, যেখানে তারা বলেছে:

"কল 1 এর জন্য প্রথমবার, স্থায়ী কলামের CASE বিবৃতিতে দ্বিতীয়বার।

অপটিমাইজার জানেন না, বা এই ক্ষেত্রে যত্ন করে না যে নিউআইডিআইডি একটি অ-বিবাদী ফাংশন এবং এটিকে দু'বার কল করে। "

অন্য একটি উপায় রাখুন, এটি আশা করা উচিত যে [NEWID () এর মধ্যে] কল 1 এর ঠিক একই মান রয়েছে যখন আপনি গণনা করার সময় সন্নিবেশ করেছিলেন।

এটি বাগের সাথে কী ঘটছে তার সমার্থক হবে, যেখানে কলআইডির জন্য NEWID তৈরি করা হয়েছে এবং তারপরে অবিরাম কলামের জন্য আবার তৈরি করা হয়েছে:

INSERT INTO @Test (Col1, Contains2) VALUES
(NEWID(), CASE WHEN (NEWID()) LIKE '%2%' THEN 1 ELSE 0 END)

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

মার্টিন প্রতি, এটি মাইক্রোসফ্টে উত্থাপিত হয়েছে ( https://connect.microsoft.com/SQLServer/Feedback/Details/2751288 ) যেখানে এই পৃষ্ঠায় ফিরে মন্তব্য এবং স্ট্যাকওভারফ্লো বিশ্লেষণ (নীচে) রয়েছে।

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