Laravel + mysql:临时表可以创建/更新,但不能从以下列表中选择:

时间:2018-08-13 18:30:04

标签: php mysql laravel temp-tables

我可以创建一个临时表,但是当我尝试从中选择时,它说该表不存在。我之所以这么认为是因为DB :: statement和DB :: select在某种程度上与数据库进行了不同的会话,但是我不确定如何修复它。

如何在同一脚本中创建临时表,将其插入并从中选择?

下面是修补匠的输出,它演示了此问题:

DB::select("select count(*) from users"); //12
DB::statement("create temporary table tempUsers like users"); //true
DB::statement("insert into tempUsers (id,email) VALUES (1, 'joe@example.com')"); //true

“选择”会话中似乎不存在

DB::select("select count(*) from tempUsers"); 
  

Illuminate \ Database \ QueryException,消息为'SQLSTATE [42S02]:基本   找不到表或视图:1146表'db.tempUsers'不存在(SQL:   从tempUsers中选择count(*))

在“声明”会话中仍然存在

DB::statement("insert into tempUsers (id,email) VALUES (2, 'bob@example.com')"); //true
DB::statement("insert into tempUsers (id,email) VALUES (1, 'joe@example.com')"); 
  

Illuminate \ Database \ QueryException,消息为'SQLSTATE [23000]:   违反完整性约束:1062密钥的重复条目“ 1”   'PRIMARY'(SQL:插入tempUsers(id,email)值   (1,'bob @ example.com'))'

$table->temporary()Blueprint一起使用时,我得到相同的行为,即

Schema::create('tempTable',function ($table) {$table->increments('id');
    $table->timestamps();
    $table->temporary();
}); 

使用Laravel 5.4,MySQL 5.6

当我连接到laravel外部的数据库时,可以很好地操作临时表并从中进行选择

2 个答案:

答案 0 :(得分:0)

如果在存储过程中创建临时表,则在存储过程完成后它将被销毁。

临时表的范围很重要,仅对特定用户可见。临时表格以井号“#”或“ @”开头非常重要,因为您似乎错过了该部分。

因此,如果您将迁移调整为:

Schema::create('#tmpTest', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});

然后运行:

php artisan migrate:fresh

要在临时表上插入数据,

  

\ DB :: statement(“插入#tmpTest(id,name)VALUES(1,   'joe@example.com')“);

要使用以下命令获取这些数据:

  

$ a = DB :: select('从* #tmpTest中选择*');       dd($ a);

它给了我结果:

enter image description here

答案 1 :(得分:0)

事实证明,问题是由我们的reader-writer设置引起的。我们将一个数据库用于写操作,将另一个数据库用于读操作。由于写入者数据库是一个临时表,并且已锁定到与写入者的当前会话,因此该写入者数据库被复制到读取数据库,{em> but temp table is not replicated

如果使用Laravel 5.5+,解决方案是在数据库连接上设置'sticky' => true。这样一来,写者在写完任何内容后都会被视为读者,从而绕过了复制延迟的问题。

由于我现在仍然坚持使用Laravel 5.4,所以我的解决方案是创建一个标准表,但是将其视为临时表并将其放在方法末尾。

DB::select("select count(*) from users"); //12

//use uniqid to ensure a unique tablename since it is now in the global namespace
$tableName=uniqid('tempUsers'); 

DB::unprepared("create table $tableName like users"); //true
DB::statement("insert into tempUsers (id,email) VALUES (1, 'joe@example.com')"); //true
DB::select("select count(*) from $tableName"); //1
//...do stuff with temp table
//...
Schema::drop($tableName);
// return