如何在Laravel中使用php artisan创建数据库视图迁移?

44

实际上,我已成功地使用PHP Artisan创建了Laravel的SQL视图,以下是步骤。

步骤1:运行以下命令:

php artisan make:migration create_overall_report_views

第二步。

打开迁移文件并添加以下代码:

class CreateOverallReportView extends Migration 
{
  /**
  * Run the migrations.
  *
  * @return void
  */
  public function up()
  {
    //
    DB::statement("
      CREATE VIEW views_overall_report AS
      (
        SELECT er.user_id as user_id, e.id AS entities_id, 
            c.status_id AS status_id, s.name AS status_name

        FROM `user_roles` er
          LEFT JOIN elists e ON e.id=er.entities_id
          LEFT JOIN `clists` c ON c.id=e.checklists_id
          LEFT JOIN `status` s ON s.id = c.overall_status_id

        WHERE s.slug = 'completed'
          AND c.deleted_at IS NULL
      )
    ");
  }

  /**
  * Reverse the migrations.
  *
  * @return void
  */
  public function down()
  {
    DB::statement('DROP VIEW IF EXISTS views_overall_report');
  }  

}

步骤 3. 通过 Laravel 查询调用和运行 SQL 视图

$items = $DB::table('views_overall_report')
            ->select('status_id', 'status_name',
                $DB::raw('count(entities_id) as counts')
            )
            ->groupBy('status_id')
            ->orderBy('counts' , 'desc')
            ->whereIn('user_id', Auth::user()->id())
            ->get();
print_r($items);

希望这有所帮助。如果有更好的解决方案,请告诉我!!


https://laravel.com/docs/master/migrations - Francesco de Guytenaere
@FrancescodeGuytenaere 链接文档有何帮助? - nullwriter
@nullwriter 请查看此帖子的历史记录,最初他找不到文档,因此我将其作为评论发布(而不是作为实际答案发布)。您可以将我的评论标记为过时。 - Francesco de Guytenaere
我以前做过这个。你实际上可以使用视图直接创建普通的Eloquent模型。php artisan make:model ViewOverallReport。然后你可以在控制器中简单地使用 $v = ViewOverallReport::all() 作为示例。 - Apit John Ismail
1
视图创建完成后,当我运行 php artisan migrate 时出现了错误。将 SQL 语句更改为 CREATE OR REPLACE VIEW 可以解决这个问题。 - Kevin Marsden
5个回答

54

发现相同的问题并在http://programmingarehard.com/2013/11/10/eloquent_and_views.html/找到了解决方案。

class CreateCompaniesView extends Migration 
{
    /**
     * 运行迁移.
     *
     * @return void
     */
    public function up()
    {
        DB::statement("CREATE VIEW companiesView AS
                        SELECT *,
                        (
                            SELECT GROUP_CONCAT(DISTINCT id SEPARATOR ',')
                            FROM people AS p
                            WHERE p.company_id = c.id
                        ) AS person_ids
                        FROM companies AS c");
    }
/** * 反向运行迁移. * * @return void */ public function down() { DB::statement("DROP VIEW companiesView"); } }

4
我已经创建了一个用于创建、重命名和删除视图的包:
https://github.com/staudenmeir/laravel-migration-views 您可以提供查询构建器实例或SQL字符串:
use Staudenmeir\LaravelMigrationViews\Facades\Schema;

class CreateOverallReportView extends Migration 
{
    public function up()
    {
        $query = DB::table('user_roles as er')->[...];
        $query = 'SELECT [...] FROM `user_roles` er [...]';

        Schema::createView('views_overall_report', $query);
    }

    public function down()
    {
        Schema::dropView('views_overall_report');
    }  
}

4

您可以这样做:

public function up()
{
  DB::statement($this->dropView());
  DB::statement($this->createView());
}

private function dropView(): string
{
   return <<<SQL
   DROP VIEW IF EXISTS `meter_reading_reports`;
   SQL;
}

private function createView(): string
{
   return <<<SQL
   CREATE VIEW `meter_reading_reports` AS
   SELECT /* … The query */
   SQL;
}

既然我们已经完成了迁移,那么其他所有的事情都跟普通的 Laravel 一样工作!

class MeterReadingReport extends Model
{
   protected $casts = [
      'day' => 'date',
   ];
   public function unit(): BelongsTo
   {
      return $this->belongsTo(Unit::class);
   }

   public function user(): BelongsTo
   {
      return $this->belongsTo(User::class);
   }
}

参考:https://stitcher.io/blog/eloquent-mysql-views

该博客介绍了使用 Laravel 中的 Eloquent ORM 来操作 MySQL 视图。通过使用视图,您可以将复杂的查询逻辑封装到视图中,并且在应用程序中重复使用。这是一个很好的技术解决方案来减少代码冗余和提高可维护性。

请问能够解释一下这个查询的语法吗?我不知道 <<< 运算符是什么意思,为什么最后以 SQL 结尾。 - elijah7
@elijah7,“<<<SQL”和“SQL;”结尾部分涉及PHP heredoc语法,而不是用于创建视图的查询的一部分。 - ferhsom

4

请在up函数中像这样编写您的迁移,并使用'CREATE OR REPLACE':

public function up()
   {

    DB::statement('CREATE OR REPLACE VIEW my_view AS SELECT name FROM users');
   }

public function down()
    {
        DB::statement('DROP VIEW my_view');
    }

1
你也可以尝试使用这个 DB::connection()->getPdo()->exec("your sql query");,它有效。
class CreateCompaniesView extends Migration 
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            DB::connection()->getPdo()->exec("CREATE VIEW companie ...");
        }

        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            DB::connection()->getPdo()->exec("DROP VIEW companies ...");
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接