Laravel Migration - 在表中添加检查约束

时间:2016-07-06 11:41:49

标签: php mysql laravel migration database-migration

我想在Laravel Migration中创建一个像这样的表 -

CREATE TABLE Payroll
(
 ID int PRIMARY KEY, 
 PositionID INT,
 Salary decimal(9,2) 
 CHECK (Salary < 150000.00)
);

我所做的是 -

Schema::create('Payroll', function (Blueprint $table)
{
    $table->increments('id');
    $table->integer('PositionID ');
    $table->decimal('Salary',9,2);
    //$table->timestamps();
});

但我不能创造这个 -

 CHECK (Salary < 150000.00)

有人可以告诉我们,如何在Laravel Migration中实施这个CHECK约束?

6 个答案:

答案 0 :(得分:16)

Blueprint类不支持添加约束(至少从Laravel 5.3开始),但 可以通过使用数据库语句直接从迁移中为表添加约束。

在您的迁移文件中

public function up ()
{
    Schema::create('payroll', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('position_id');
        $table->decimal('salary',9,2);
    });

    // Add the constraint
    DB::statement('ALTER TABLE payroll ADD CONSTRAINT chk_salary_amount CHECK (salary < 150000.00);');
}

答案 1 :(得分:4)

我不认为这是Laravel迁移中的一项功能。我认为这必须在您的模型或验证逻辑中,除非您手动将其添加到MYSQL

这就是我要做的事情

$this->validate($request, [
    'Salary' => 'max:150000.00',
]);

答案 2 :(得分:2)

此功能未包含在Blueprint类中,因此您无法在迁移文件中执行此操作。

但是在您的Payroll模型中,您可以创建一个mutator:

class Payroll extends Model{

    public function setSalaryAttribute($value){
        $this->attributes['Salary'] = $value < 150000.00 ? $value : 150000.00;
    }

}

因此,当创建或更新工资单Salary属性时,将自动触发此方法,并检查新值是否超过150000

编辑:您应该查看Laravel文档中的mutators documentation

答案 3 :(得分:1)

MySQL / Mariadb忽略CHECK约束,因此您必须使用触发器。触发器只能设置为在INSERT / UPDATE / DELETE之一上运行,这意味着如果我们希望它在INSERT和UPDATE上运行,我们必须创建一个过程,然后从两个单独的触发器中调用它。

DB :: statement()不支持此语法,因此我们必须使用PDO :: exec()。

以下是迈克尔示例的TRIGGER语法:

public function up()
{
    Schema::create('Payroll', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('position_id');
        $table->decimal('salary', 9, 2);
    });

    DB::connection()->getPdo()->exec("
        -- Create the procedure
        CREATE PROCEDURE payroll_check_salary_amount (salary INT)
        BEGIN
            IF NOT (salary < 150000.00) THEN
                SIGNAL SQLSTATE '45000' SET message_text = 'salary must be less than 150000.00';
            END IF;
        END;

        -- Create the INSERT trigger
        CREATE TRIGGER payroll_check_salary_amount_insert BEFORE INSERT ON Payroll
        FOR EACH ROW
        BEGIN
            CALL payroll_check_salary_amount(NEW.salary);
        END;

        -- Create the UPDATE trigger
        CREATE TRIGGER payroll_check_salary_amount_update BEFORE UPDATE ON Payroll
        FOR EACH ROW
        BEGIN
            CALL payroll_check_salary_amount(NEW.salary);
        END;
    ");
}

public function down()
{
    Schema::dropIfExists('Payroll');
    DB::statement('DROP PROCEDURE IF EXISTS payroll_check_salary_amount');
}

答案 4 :(得分:0)

要添加约束,您可以编写以下代码

$table->enum('choices', ['foo', 'bar']);

但是,如果要使用算术运算,则解决方案是使用** @ Michael **

提到的sql语句进行制作
// Add the constraint
DB::statement('ALTER TABLE payroll ADD CONSTRAINT chk_salary_amount CHECK (salary < 150000.00);');

检查以下link以获取更多信息

答案 5 :(得分:0)

public function up ()
{
    Schema::create('payroll', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('p_id');
        $table->decimal('payment',9,2);
    });

    // Add the constraint`enter code here`
    DB::statement('ALTER TABLE payroll ADD CONSTRAINT check_salary_amount CHECK (payment < 2000.00);');
}