MySQL 5.6中生成列的替代方法是什么

时间:2018-06-18 06:08:22

标签: mysql sql database mysql-5.6 virtual-column

我有一个MySQL alter语句

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Globalization;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {

            Course c1 = new Course{
                cName = "Course 1",
                Start_Time = "10:00",
                End_Time = "10:50",
                Days = new List<string>{ "Mon", "Tue", "Wed"}
            };

            Course c2 = new Course{
                cName = "Course 2",
                Start_Time = "10:40",
                End_Time = "11:20",
                Days = new List<string>{ "Wed", "Thu", "Fri"}
            };

            Course c3 = new Course{
                cName = "Course 3",
                Start_Time = "11:30",
                End_Time = "12:20",
                Days = new List<string>{ "Mon", "Tue", "Fri"}
            };


            bool areC1C2Clashing = areCoursesClashing(c1, c2);
            Console.WriteLine("Are c1 & c2 clashing - " + areC1C2Clashing);
            Console.WriteLine();

            bool areC2C3Clashing = areCoursesClashing(c2, c3);
            Console.WriteLine("Are c2 & c3 clashing - " + areC2C3Clashing);
            Console.WriteLine();

            bool areC1C3Clashing = areCoursesClashing(c1, c3);
            Console.WriteLine("Are c1 & c3 clashing - " + areC1C3Clashing);
            Console.WriteLine();
        }

        public static bool areCoursesClashing(Course cA, Course cB){
            bool clashDetected = false;
            foreach(var coruseDay in cA.Days){
                if(cB.Days.Contains(coruseDay)){

                    DateTime cAStartTime = DateTime.ParseExact(cA.Start_Time, "HH:mm", CultureInfo.InvariantCulture);
                    DateTime cAEndTime = DateTime.ParseExact(cA.End_Time, "HH:mm", CultureInfo.InvariantCulture);
                    DateTime cBStartTime = DateTime.ParseExact(cB.Start_Time, "HH:mm", CultureInfo.InvariantCulture);
                    DateTime cBEndTime = DateTime.ParseExact(cB.End_Time, "HH:mm", CultureInfo.InvariantCulture);

                    if( cAStartTime < cBEndTime && cBStartTime < cAEndTime){
                        Console.WriteLine("WARNING!!! Classes clash for --> " + cA.cName + " & " + cB.cName);
                        clashDetected = true;
                    }
                }
            }
            return clashDetected;
        }
    }

    public class Course {
        public string cName { get; set; }
        public string Start_Time { get; set; }
        public string End_Time { get; set; }
        public List<string> Days { get; set; }
    }
}

在唯一约束中添加ALTER TABLE `employee` ADD `employee_name_generator` CHAR(20) GENERATED ALWAYS AS  (COALESCE(concat(`employee_name`), '^')) VIRTUAL; 时需要这样做。这在MySQL 5.7以后工作正常。但我需要的环境有MySQL 5.6。是否有MySQL 5.6的替代方案?

2 个答案:

答案 0 :(得分:3)

如果您的早期版本的MySQL不支持生成的列,那么您必须在查询时计算该列。一种选择是观点:

CREATE VIEW yourView AS (
    SELECT *, COALESCE(CONCAT(employee_name, '^')) AS employee_name_generator
    FROM employee
)

MySQL不支持物化视图(直接)。因此,如果您确实需要物化视图的行为,则必须使用上面给出的视图中的选择逻辑创建临时表。

答案 1 :(得分:2)

您可以将触发器用作解决方法,并获得类似的结果。

ALTER TABLE `employee`
ADD `employee_name_generator` CHAR(20);

delimiter //
create trigger trig_create_employee_name_generator before insert on `employee`
for each row
begin
   set NEW.`employee_name_generator` = COALESCE(concat(NEW.`employee_name`), '^');
end
//

如果您还要在插入后更新employee_name字段,则还需要触发更新:

delimiter //
create trigger trig_update_employee_name_generator before update on `employee`
for each row
begin
   set NEW.`employee_name_generator` = COALESCE(concat(NEW.`employee_name`), '^');
end
//

请记住,在MySQL 5.6中,每个表在插入前仅获得一个触发器,而在更新时仅获得一个触发器,因此,如果需要多个生成的列,则可以将set语句链接到“开始”之间的同一触发器中。和“结束”。