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

问题描述 投票:7回答:6

我想在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)

任何人都可以告诉,如何在CHECK中实现这个Laravel Migration约束?

php mysql laravel migration database-migration
6个回答
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);');
}

4
投票

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

这就是我要做的

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

2
投票

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

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

class Payroll extends Model{

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

}

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

编辑:您应该看看Laravel Docs中的mutators documentation


1
投票

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

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

这是Michael的例子的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');
}

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以获取更多信息


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);');
}
© www.soinside.com 2019 - 2024. All rights reserved.