Я могу создать временную таблицу, но затем, когда я пытаюсь выбрать из нее, он говорит, что таблица не существует. Я полагаю, потому что 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, '[email protected]')"); //true
не существует в сеансе select
DB::select("select count(*) from tempUsers");
Осветить \ Database \ QueryException с сообщением ‘SQLSTATE [42S02]: База
таблица или представление не найдено: 1146 Таблица ‘db.tempUsers’ не существует (SQL:
выбрать количество (*) из tempUsers) ‘
до сих пор существует на сессии «заявление»
DB::statement("insert into tempUsers (id,email) VALUES (2, '[email protected]')"); //true
DB::statement("insert into tempUsers (id,email) VALUES (1, '[email protected]')");
Осветите \ Database \ QueryException с сообщением ‘SQLSTATE [23000]:
Нарушение ограничения целостности: 1062 Дублирующая запись ‘1’ для ключа
«ПЕРВИЧНЫЙ» (SQL: INSERT INTO tempUsers (id, email) ЗНАЧЕНИЯ
(1, ‘боб @ example.com’))»
Я получаю идентичное поведение, используя $table->temporary()
с Blueprint
т.е.
Schema::create('tempTable',function ($table) {$table->increments('id');
$table->timestamps();
$table->temporary();
});
Использование Laravel 5.4, MySQL 5.6
Я могу манипулировать и выбирать из временных таблиц очень хорошо, когда я подключен к БД за пределами Laravel
Если вы создаете временную таблицу внутри хранимой процедуры, она уничтожается после завершения хранимой процедуры.
Область действия временной таблицы важна, видна только конкретному пользователю. Временные таблицы начинаются с символа фунта ‘#’ или ‘@’, что очень важно, так как кажется, что вы пропустили эту часть.
Так что, если вы настроите свою миграцию на:
Schema::create('#tmpTest', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
});
Затем запустите:
php artisan migrate:fresh
Чтобы вставить данные в временную таблицу:
\ DB :: Statement («вставить в
#tmpTest
(id, name) ЗНАЧЕНИЯ (1,
‘[email protected]’) «);
Чтобы получить эти данные с помощью выберите:
$ a = DB :: select (‘select * from
#tmpTest
«);
дд ($ а);
Это дает мне результат:
Оказывается, проблема вызвана нашими Читатель-писатель настроить. Мы используем одну базу данных для записи, а другую для чтения. База данных писателя реплицируется в базу данных чтения, но временная таблица не реплицируется, так как это временная таблица и она заблокирована для текущего сеанса с писателем.
При использовании 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, '[email protected]')"); //true
DB::select("select count(*) from $tableName"); //1
//...do stuff with temp table
//...
Schema::drop($tableName);
// return