বিদেশী কী সীমাবদ্ধতা লঙ্ঘন সমস্যা


10

আমি 3 পরিস্থিতি চিহ্নিত করেছি।

  1. কোনও ছাত্র নেই যার নাম নেই।
  2. ভর্তিচ্ছু শিক্ষার্থী তবে গ্রেড নেই।
  3. তালিকাভুক্তি এবং গ্রেড সহ একটি ছাত্র।

জিপিএ গণনা করার জন্য তালিকাভুক্তির টেবিলে একটি ট্রিগার রয়েছে। যদি কোনও শিক্ষার্থীর গ্রেড থাকে তবে এটি GPA টেবিলটিতে প্রবেশ বা প্রবেশের আপডেট করবে; কোনও গ্রেড নেই, কোনও জিপিএ টেবিল প্রবেশ নেই।

আমি কোনও শিক্ষার্থী নাম নথিভুক্ত (# 1) মুছতে পারি। আমি তালিকাভুক্তি এবং গ্রেড (উপরে # 3) সহ একজন ছাত্র মুছতে পারি। তবে আমি তালিকাভুক্ত শিক্ষার্থী কিন্তু গ্রেড (# 2) সহ মুছে ফেলতে পারি না। আমি একটি রেফারেন্স সীমাবদ্ধতা লঙ্ঘন পাই।

DELETE বিবৃতিটি "FK_dbo.GPA_dbo.Student_StudentID" সীমাবদ্ধতার সাথে সাংঘর্ষিক। এই দ্বন্দ্বটি ডাটাবেস "", টেবিল "dbo.GPA", কলাম 'স্টুডেন্টআইডি' তে ঘটেছিল।

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

আমি আমার ট্রিগারটি প্যাচ করেছি যাতে আমি এগিয়ে যেতে পারি। এখন, আপনি যদি তালিকাভুক্তি করে থাকেন তবে ট্রিগারটি আপনাকে জিপিএ টেবিলের মধ্যে সন্নিবেশ করায় যাই হোক না কেন। তবে আমি অন্তর্নিহিত সমস্যা বুঝতে পারি না। কোন ব্যাখ্যা সবচেয়ে প্রশংসা হবে।

এর মূল্য কী:

  1. ভিজ্যুয়াল স্টুডিও 2013 পেশাদার।
  2. আইআইএস এক্সপ্রেস (ভিএস2013 এর অভ্যন্তরীণ)।
  3. এএসটি.এনইটি ওয়েব অ্যাপসটি অ্যান্টিটি ফ্রেমওয়ার্ক ব্যবহার করে .1.১.১।
  4. এমএস এসকিউএল সার্ভার 2014 এন্টারপ্রাইজ।
  5. জিপিএ.ভ্যালু হ্রাসযোগ্য।
  6. তালিকাভুক্তি.গ্রাডআইডি নালাগুলি।

এখানে ডাটাবেসের একটি স্নিপেট রয়েছে:

ডাটাবেস ইমেজ

- সম্পাদনা -

টেবিলগুলি এন্টি ফ্রেমওয়ার্ক দ্বারা তৈরি করা হয়েছে, আমি এসকিউএল সার্ভার ম্যানেজমেন্ট স্টুডিওগুলি এগুলি উত্পাদন করতে ব্যবহার করেছি।

এখানে সীমাবদ্ধতা সহ সারণী বিবৃতি তৈরি করুন:

GPA টেবিল:

CREATE TABLE [dbo].[GPA](
    [StudentID] [int] NOT NULL,
    [Value] [float] NULL,
  CONSTRAINT [PK_dbo.GPA] PRIMARY KEY CLUSTERED 
  (
    [StudentID] ASC
  )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
         ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

ALTER TABLE [dbo].[GPA]  WITH CHECK 
  ADD  CONSTRAINT [FK_dbo.GPA_dbo.Student_StudentID] 
  FOREIGN KEY([StudentID])
  REFERENCES [dbo].[Student] ([ID])

ALTER TABLE [dbo].[GPA] 
  CHECK CONSTRAINT [FK_dbo.GPA_dbo.Student_StudentID]

Enrollment টেবিল:

CREATE TABLE [dbo].[Enrollment](
    [EnrollmentID] [int] IDENTITY(1,1) NOT NULL,
    [CourseID] [int] NOT NULL,
    [StudentID] [int] NOT NULL,
    [GradeID] [int] NULL,
  CONSTRAINT [PK_dbo.Enrollment] PRIMARY KEY CLUSTERED 
  (
    [EnrollmentID] ASC
  )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
         ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

ALTER TABLE [dbo].[Enrollment]  WITH CHECK 
  ADD  CONSTRAINT [FK_dbo.Enrollment_dbo.Course_CourseID] 
  FOREIGN KEY([CourseID])
  REFERENCES [dbo].[Course] ([CourseID])
  ON DELETE CASCADE

ALTER TABLE [dbo].[Enrollment] 
  CHECK CONSTRAINT [FK_dbo.Enrollment_dbo.Course_CourseID]

ALTER TABLE [dbo].[Enrollment]  WITH CHECK 
  ADD  CONSTRAINT [FK_dbo.Enrollment_dbo.Grade_GradeID] 
  FOREIGN KEY([GradeID])
  REFERENCES [dbo].[Grade] ([GradeID])

ALTER TABLE [dbo].[Enrollment] 
  CHECK CONSTRAINT [FK_dbo.Enrollment_dbo.Grade_GradeID]

ALTER TABLE [dbo].[Enrollment]  WITH CHECK 
  ADD  CONSTRAINT [FK_dbo.Enrollment_dbo.Student_StudentID] 
  FOREIGN KEY([StudentID])
  REFERENCES [dbo].[Student] ([ID])
  ON DELETE CASCADE

ALTER TABLE [dbo].[Enrollment] 
  CHECK CONSTRAINT [FK_dbo.Enrollment_dbo.Student_StudentID]

Student টেবিল:

CREATE TABLE [dbo].[Student](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [EnrollmentDate] [datetime] NOT NULL,
    [LastName] [nvarchar](50) NOT NULL,
    [FirstName] [nvarchar](50) NOT NULL,
  CONSTRAINT [PK_dbo.Student] PRIMARY KEY CLUSTERED 
  (
    [ID] ASC
  )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
         ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

ট্রিগারগুলি এখানে :

CREATE TRIGGER UpdateGPAFromUpdateDelete
ON Enrollment
AFTER UPDATE, DELETE AS
BEGIN
    DECLARE @UpdatedStudentID AS int
    SELECT @UpdatedStudentID = StudentID FROM DELETED
    EXEC MergeGPA @UpdatedStudentID
END

CREATE TRIGGER UpdateGPAFromInsert
ON Enrollment
AFTER INSERT AS
--DECLARE @InsertedGradeID AS int
--SELECT @InsertedGradeID = GradeID FROM INSERTED
--IF @InsertedGradeID IS NOT NULL
    BEGIN
        DECLARE @InsertedStudentID AS int
        SELECT @InsertedStudentID = StudentID FROM INSERTED
        EXEC MergeGPA @InsertedStudentID
    END

এগিয়ে যাওয়ার প্যাচটি হ'ল ট্রিগারটিতে থাকা এই লাইনগুলিকে মন্তব্য করা AFTER INSERT

এখানে সঞ্চিত পদ্ধতি :

CREATE PROCEDURE MergeGPA @StudentID int AS
MERGE GPA AS TARGET
USING (SELECT @StudentID) as SOURCE (StudentID)
ON (TARGET.StudentID = SOURCE.StudentID)
WHEN MATCHED THEN
    UPDATE
        SET Value = (SELECT Value FROM GetGPA(@StudentID))
WHEN NOT MATCHED THEN
INSERT (StudentID, Value)
    VALUES(SOURCE.StudentID, (SELECT Value FROM GetGPA(@StudentID)));

এখানে ডাটাবেস ফাংশন :

CREATE FUNCTION GetGPA (@StudentID int) 
RETURNS TABLE
AS RETURN
SELECT ROUND(SUM (StudentTotal.TotalCredits) / SUM (StudentTotal.Credits), 2) Value
    FROM (
        SELECT 
            CAST(Credits as float) Credits
            , CAST(SUM(Value * Credits) as float) TotalCredits
        FROM 
            Enrollment e 
            JOIN Course c ON c.CourseID = e.CourseID
            JOIN Grade g  ON e.GradeID = g.GradeID
        WHERE
            e.StudentID = @StudentID AND
            e.GradeID IS NOT NULL
        GROUP BY
            StudentID
            , Value
            , e.courseID
            , Credits
    ) StudentTotal

নিয়ামকের মুছে ফেলা পদ্ধতিটি থেকে এখানে ডিবাগ আউটপুট দেওয়া হচ্ছে, নির্বাচনের বিবৃতিটি কী মুছতে হবে তা অনুসন্ধান পদ্ধতি method এই শিক্ষার্থীর 3 টি নথিভুক্তি রয়েছে, 3 REFERENCEয় তালিকাভুক্তি মুছে ফেলা সীমাবদ্ধতার সমস্যাটি ঘটে। আমি অনুমান করি যে EF একটি লেনদেন ব্যবহার করছে কারণ তালিকাভুক্তিগুলি মোছা হয়নি।

iisexpress.exe Information: 0 : Component:SQL Database;Method:SchoolInterceptor.ReaderExecuted;Timespan:00:00:00.0004945;Properties:
Command: SELECT 
    [Project2].[StudentID] AS [StudentID], 
    [Project2].[ID] AS [ID], 
    [Project2].[EnrollmentDate] AS [EnrollmentDate], 
    [Project2].[LastName] AS [LastName], 
    [Project2].[FirstName] AS [FirstName], 
    [Project2].[Value] AS [Value], 
    [Project2].[C1] AS [C1], 
    [Project2].[EnrollmentID] AS [EnrollmentID], 
    [Project2].[CourseID] AS [CourseID], 
    [Project2].[StudentID1] AS [StudentID1], 
    [Project2].[GradeID] AS [GradeID]
    FROM ( SELECT 
        [Limit1].[ID] AS [ID], 
        [Limit1].[EnrollmentDate] AS [EnrollmentDate], 
        [Limit1].[LastName] AS [LastName], 
        [Limit1].[FirstName] AS [FirstName], 
        [Limit1].[StudentID] AS [StudentID], 
        [Limit1].[Value] AS [Value], 
        [Extent3].[EnrollmentID] AS [EnrollmentID], 
        [Extent3].[CourseID] AS [CourseID], 
        [Extent3].[StudentID] AS [StudentID1], 
        [Extent3].[GradeID] AS [GradeID], 
        CASE WHEN ([Extent3].[EnrollmentID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
        FROM   (SELECT TOP (2) 
            [Extent1].[ID] AS [ID], 
            [Extent1].[EnrollmentDate] AS [EnrollmentDate], 
            [Extent1].[LastName] AS [LastName], 
            [Extent1].[FirstName] AS [FirstName], 
            [Extent2].[StudentID] AS [StudentID], 
            [Extent2].[Value] AS [Value]
            FROM  [dbo].[Student] AS [Extent1]
            LEFT OUTER JOIN [dbo].[GPA] AS [Extent2] ON [Extent1].[ID] = [Extent2].[StudentID]
            WHERE [Extent1].[ID] = @p__linq__0 ) AS [Limit1]
        LEFT OUTER JOIN [dbo].[Enrollment] AS [Extent3] ON [Limit1].[ID] = [Extent3].[StudentID]
    )  AS [Project2]
    ORDER BY [Project2].[StudentID] ASC, [Project2].[ID] ASC, [Project2].[C1] ASC: 
iisexpress.exe Information: 0 : Component:SQL Database;Method:SchoolInterceptor.NonQueryExecuted;Timespan:00:00:00.0012696;Properties:
Command: DELETE [dbo].[Enrollment]
WHERE ([EnrollmentID] = @0): 
iisexpress.exe Information: 0 : Component:SQL Database;Method:SchoolInterceptor.NonQueryExecuted;Timespan:00:00:00.0002634;Properties:
Command: DELETE [dbo].[Enrollment]
WHERE ([EnrollmentID] = @0): 
iisexpress.exe Information: 0 : Component:SQL Database;Method:SchoolInterceptor.NonQueryExecuted;Timespan:00:00:00.0002512;Properties:
Command: DELETE [dbo].[Enrollment]
WHERE ([EnrollmentID] = @0): 
iisexpress.exe Error: 0 : Error executing command: DELETE [dbo].[Student]
WHERE ([ID] = @0) Exception: System.Data.SqlClient.SqlException (0x80131904): The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.GPA_dbo.Student_StudentID". The conflict occurred in database "<databasename>", table "dbo.GPA", column 'StudentID'.
The statement has been terminated.

উত্তর:


7

এটি সময়ের প্রশ্ন। শিক্ষার্থী # 1 মোছার বিষয়টি বিবেচনা করুন:

  1. সারিটি Studentটেবিল থেকে মুছে ফেলা হয়েছে
  2. ক্যাসকেড মোছা এতে সম্পর্কিত সারিগুলি সরিয়ে দেয় Enrollment
  3. বিদেশী কী সম্পর্ক GPA-> Studentচেক করা হয়েছে
  4. ট্রিগার আগুন, কল MergeGPA

এই মুহুর্তে, সারণীতে MergeGPA# 1 শিক্ষার্থীর জন্য কোনও প্রবেশ রয়েছে কিনা তা পরীক্ষা করে দেখুন GPA। এটি নেই (অন্যথায় পদক্ষেপ 3 এফকে চেক একটি ত্রুটি বাড়িয়ে তুলেছিল)।

সুতরাং, শিক্ষার্থী # 1 এর জন্য সারি করার চেষ্টা করার WHEN NOT MATCHEDধারাটি । এই প্রচেষ্টাটি ব্যর্থ হয়েছে (এফকে ত্রুটির সাথে) কারণ ছাত্রী # 1 ইতিমধ্যে টেবিল থেকে মুছে ফেলা হয়েছে (1 ধাপে)।MergeGPAINSERTGPAStudent


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

-1

সমস্ত কিছু না পড়ে, কেবল চিত্রটি: আপনি এনরোলমেন্টে একটি প্রবেশিকা বা জিপিএর একটিতে আপনি মুছে ফেলতে চান এমন শিক্ষার্থীর দিকে নির্দেশ করছেন।

আপনি শিক্ষার্থী এন্ট্রি মুছতে পারার আগে বিদেশী কীগুলির সাথে প্রবেশকারীদের প্রথমে মুছে ফেলা দরকার (বা কীগুলি বাতিল হয়ে যায়, তবে এটি খারাপ অভ্যাস)।

এছাড়াও কিছু ডাটাবেসে ক্যাসকেড মুছে ফেলা হয়েছে, যা আপনি মুছতে চান তার বিদেশী চাবিযুক্ত যে কোনও এন্ট্রি মুছে ফেলবে।

অন্য উপায় হ'ল এগুলি বিদেশী কী হিসাবে ঘোষণা না করা এবং কেবল কী মানটি ব্যবহার করা, তবে এটির প্রস্তাবও দেওয়া হয়নি।


যে ক্ষেত্রে এটি ব্যর্থ হচ্ছে ক্ষেত্রে এনরোলমেন্টে প্রবেশ রয়েছে তবে জিপিএতে একটি নয়।
ডাউনটাউন

মুছে ফেলতে ক্যাসকেড এবং কিছু ছাড়াই আপনার কিছু বাধা রয়েছে। সমস্ত সীমাবদ্ধতার সাথে লাইনটি যুক্ত করার চেষ্টা করুন। এর পরে সমস্ত ট্রিগার অক্ষম করার চেষ্টা করা হবে এবং সেই পরীক্ষার পরে একটি সর্বনিম্ন সেটআপ দিয়ে। শুভকামনা
ব্যবহারকারী 44286

আমি এই ON DELETE CASCADEবিবৃতি দেখতে । এই সারণী তৈরির বিবৃতিগুলির কোনওটিই, বা মোছার বিবৃতিগুলি হস্ত লিখিত নয়, সেগুলি সমস্ত সত্তা ফ্রেমওয়ার্ক দ্বারা তৈরি। ক্যাসকেডগুলি হ'ল কারণ তালিকাভুক্তিতে বিদেশী কী রয়েছে যা এটি প্রাথমিক কী নয়; জিপিএর বিদেশী কী বাধা এটি প্রাথমিক কী তাই এটির জন্য ক্যাসকেড লাগবে না। আমি এটি পরীক্ষা করেছি, আপনি যদি কোনও জিপিএ টেবিল এন্ট্রি সহ কোনও শিক্ষার্থীকে মুছুন তবে এন্ট্রি মুছে যাবে। একমাত্র ইস্যুতে নাম নথিভুক্ত শিক্ষার্থী তবে জিপিএ নেই।
ডাউনটাউন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.