我可以创建一个临时表,但是当我尝试从中选择时,它说该表不存在。我之所以这么认为是因为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外部的数据库时,可以很好地操作临时表并从中进行选择
答案 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);
它给了我结果:
答案 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