我有 4 张 table ,看起来像......
CREATE TABLE `Faculty` (
`FID` varchar(10) NOT NULL,
`Name` varchar(30) NOT NULL,
`DOB` date NOT NULL,
`Sem` varchar(1) NOT NULL,
`Section` varchar(1) NOT NULL,
`Subject Code` varchar(6) NOT NULL,
`Dep` varchar(3) NOT NULL,
`Hours Taken` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `Student` (
`USN` varchar(10) NOT NULL,
`DOB` date NOT NULL,
`Dep` varchar(3) NOT NULL,
`SEM` int(1) NOT NULL,
`Class` varchar(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `Student Attendance` (
`USN` varchar(10) NOT NULL,
`Subject Code` varchar(6) NOT NULL,
`Attendance` int(11) DEFAULT '0',
`Absent Days` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `Subjects` (
`Subject` varchar(40) NOT NULL,
`Subject Code` varchar(6) NOT NULL,
`Dep` varchar(3) NOT NULL,
`Sem` int(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
现在我需要确保学生的出勤小时数(学生出勤
。出勤
)不大于教师的出勤小时数成员(member)已为该特定科目(科目代码
)修读(院系
.学时
)。所以我写了一个触发器来检查是否满足上述条件,以检查插入和更新。
如果小时数(学生出勤
.出勤
)大于我设置的学生出勤
。出勤
到某个字符串。我希望这能作为一个断言并给我一个错误。
CREATE TRIGGER `HoursCheckonInsert` BEFORE INSERT ON `Student
Attendance`
FOR EACH ROW SET NEW.Attendance= IF(
( Select k.USN, s.`Subject Code`,f.`Hours Taken`,s.Attendance
From Faculty f, `Student Attendance` s, Student k
where s.`Subject Code` = f.`Subject Code` AND k.SEM = f.Sem AND k.Class=f.Section AND s.USN=k.USN AND
NEW.Attendance < f.`Hours Taken` OR NEW.Attendance = f.`Hours Taken`
),
NEW.Attendance,
'abcdef'
)
CREATE TRIGGER `HoursCheckonUpdate` BEFORE UPDATE ON `Student Attendance
FOR EACH ROW SET NEW.Attendance= IF(
(Select k.USN, s.`Subject Code`,f.`Hours Taken`,s.Attendance
From Faculty f, `Student Attendance` s, Student k
where NEW.`Subject Code`=f.`Subject Code` AND NEW.USN=k.USN AND
NEW.USN=s.USN AND k.SEM=f.Sem AND k.Class=f.Section AND k.DEP=f.DEP
AND (NEW.Attendance < f.`Hours Taken` OR NEW.Attendance = f.`Hours Taken`)
),
NEW.Attendance,
'abcdef'
)
当我尝试将值插入学生出勤时,出现此错误:
INSERT INTO `Student Attendance` (`USN`, `Subject Code`, `Attendance`, `Absent Days`) VALUES ('1KS15BT001', '15BT44', '0', '0');
Error:
#1241 - Operand should contain 1 column(s)
我是 MySQL 触发器的新手。
最佳答案
MySQL 的 IF()
函数需要一个标量表达式作为其第一个参数。标量表达式意味着它必须是一列,最多一行。
您使用的子查询有四列,行数未知。
从您的评论来看,您似乎只对是否有零行或多于零行匹配条件感兴趣。您是对的,如果您使用 EXISTS
谓词来测试子查询而不是在标量表达式中返回子查询的结果,那么选择什么列并不重要。
您应该使用 EXISTS
谓词来执行您想要执行的操作。请参阅https://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html
CREATE TRIGGER `HoursCheckonInsert`
BEFORE INSERT ON `Student Attendance`
FOR EACH ROW
SET NEW.Attendance = IF(
EXISTS(
SELECT *
FROM Faculty AS f
JOIN `Student Attendance` AS s ON s.`Subject Code` = f.`Subject Code`
JOIN Student AS k ON k.SEM = f.Sem AND k.Class=f.Section AND k.uSN = s.USN
WHERE NEW.Attendance <= f.`Hours Taken`),
NEW.Attendance,
'abcdef');
那么您将哪些列放入选择列表中实际上并不重要。我在上面展示了使用 SELECT *
的情况。没关系,因为 EXISTS
仅检查是否存在任何匹配的行,并且根本不会有结果集 - 只有 bool 值是否为零或大于零行。
您还应该使用 JOIN
语法来代替过时的逗号样式语法进行连接。我在上面的示例中展示了这一点。
关于MYSQL触发器插入和更新错误: MySQL error 1241: Operand should contain 1 column(s),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46993315/