Laravel + mysql: временная таблица может быть создана / обновлена, но не может быть выбрана из:

Я могу создать временную таблицу, но затем, когда я пытаюсь выбрать из нее, он говорит, что таблица не существует. Я полагаю, потому что 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

0

Решение

Если вы создаете временную таблицу внутри хранимой процедуры, она уничтожается после завершения хранимой процедуры.

Область действия временной таблицы важна, видна только конкретному пользователю. Временные таблицы начинаются с символа фунта ‘#’ или ‘@’, что очень важно, так как кажется, что вы пропустили эту часть.

Так что, если вы настроите свою миграцию на:

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«);
дд ($ а);

Это дает мне результат:

введите описание изображения здесь

0

Другие решения

Оказывается, проблема вызвана нашими Читатель-писатель настроить. Мы используем одну базу данных для записи, а другую для чтения. База данных писателя реплицируется в базу данных чтения, но временная таблица не реплицируется, так как это временная таблица и она заблокирована для текущего сеанса с писателем.

При использовании 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
0

По вопросам рекламы [email protected]