Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 尝试将带有子查询的CHECK转换为SQL中的函数时出现问题_Sql Server_Tsql_Ddl_Stored Functions_Check Constraints - Fatal编程技术网

Sql server 尝试将带有子查询的CHECK转换为SQL中的函数时出现问题

Sql server 尝试将带有子查询的CHECK转换为SQL中的函数时出现问题,sql-server,tsql,ddl,stored-functions,check-constraints,Sql Server,Tsql,Ddl,Stored Functions,Check Constraints,我已经为这个问题坐了好几个小时了,我快要发疯了。我希望每个学生最多只能学习45门课程。在这一点上,它禁止我添加超过45个课程编辑总数。我应该如何重新安排函数CheckCredits CREATE TABLE Student ( studentID VARCHAR(5), studentName VARCHAR(20), studentAddress VARCHAR(20), CONSTRAINT student_pk PRIMARY KEY(studentID)

我已经为这个问题坐了好几个小时了,我快要发疯了。我希望每个学生最多只能学习45门课程。在这一点上,它禁止我添加超过45个课程编辑总数。我应该如何重新安排函数CheckCredits

CREATE TABLE Student
(
    studentID VARCHAR(5),
    studentName VARCHAR(20),
    studentAddress VARCHAR(20),
    CONSTRAINT student_pk PRIMARY KEY(studentID)
)

CREATE TABLE Course
(
    courseID VARCHAR(5),
    courseCredits INT,
    courseName VARCHAR(20),
    CONSTRAINT course_pk PRIMARY KEY(courseID)
)

CREATE TABLE Studies
(
    studentID VARCHAR(5),
    courseID VARCHAR(5),
    CONSTRAINT studies_pk PRIMARY KEY(studentID,courseID),
    CONSTRAINT studies_fk_student FOREIGN KEY(studentID) REFERENCES Student(studentID) ON DELETE CASCADE,
    CONSTRAINT studies_fk_course FOREIGN KEY(courseID) REFERENCES Course(courseID) ON DELETE CASCADE
)

CREATE TABLE HasStudied
(
    studentID VARCHAR(5),
    courseID VARCHAR(5),
    grade VARCHAR(1),
    CONSTRAINT has_studied_pk PRIMARY KEY(studentID,courseID),
    CONSTRAINT has_studied_fk_student FOREIGN KEY(studentID) REFERENCES Student(studentID) ON DELETE CASCADE,
    CONSTRAINT has_studied_fk_course FOREIGN KEY(courseID) REFERENCES Course(courseID) ON DELETE CASCADE
)

GO
CREATE FUNCTION CheckCredits()
RETURNS INT
AS 
BEGIN
   DECLARE @returnvalue INT
   SELECT @returnvalue = (SELECT SUM(courseCredits) FROM Course c where c.courseID IN(
    SELECT s.courseID FROM Studies s JOIN Student st ON s.studentID = st.studentID OR c.courseID = s.courseID))
   RETURN @returnvalue
END;
GO

ALTER TABLE Studies 
ADD CONSTRAINT chkCredits CHECK (dbo.CheckCredits() <= 45);  



INSERT INTO Student VALUES('S1', 'Joe', 'Street')
INSERT INTO Student VALUES('S2', 'Joe', 'Street')
INSERT INTO Student VALUES('S3', 'Joe', 'Street')
INSERT INTO Student VALUES('S4', 'Joe', 'Street')

INSERT INTO Course VALUES('C1', 45, 'Biology')
INSERT INTO Course VALUES('C2', 15, 'History')
INSERT INTO Course VALUES('C3', 35, 'English')
INSERT INTO Course VALUES('C4', 20, 'Music')

INSERT INTO Studies VALUES('S1', 'C1')
INSERT INTO Studies VALUES('S2', 'C2')
INSERT INTO Studies VALUES('S3', 'C3')


更改函数以返回每个学生的最大学分。像这样:

CREATE FUNCTION CheckCredits()
RETURNS INT
AS 
BEGIN
    DECLARE @returnvalue INT
    SELECT TOP 1 @returnvalue = SUM(courseCredits) 
    FROM Studies s 
    JOIN Course c ON s.courseID = c.courseID 
    GROUP BY s.studentID 
    ORDER BY SUM(courseCredits)  desc 

   RETURN @returnvalue
END;
GO

现在我不能把S2和C2相加,或者把S3和C3相加,因为S1研究C1,C1有45个点。所以它不认为学生是独立的,检查功能被应用到所有的学生和课程上。因为它返回任何学生注册的所有课程的课程编辑总数,所以很可能大于45。如果使用一个触发器,只检查在相应表中插入或更新的行,您可能会做得更好。请注意,每个语句触发一次,而不是行。谢谢您的回复。我很难理解触发器。是否无法使用函数执行此操作?可以使用函数执行此操作,但无法访问正在更新的特定行。因此,它必须检查每个学生的课程学分。首先编写一个查询,返回每个学生的课程总学分。然后你的支票就变成了一种情况,当存在时,选择Sum courseCredits as totalCredits from。。。按总学分>45的学生分组,然后按1或0结束。随着学生人数的增加,效率不高。和课程。还有多年的数据,别忘了其他的检查。如果课程更新为courseCredits设置为50,那么会发生什么?即使将一个从15更改为20,也可能会导致学生违反您的规则,但只有在Studies表中的一些无关活动导致意外的约束违反之前,才会检测到该规则。非常感谢!这真是太棒了。现在让我试着理解一下:它选择课程总数最高的学生,然后将其插入@returnvalue。这与ALTER TABLE研究一起添加了约束chk_Credits CHECK dbo.CheckCredits