вставить несколько строк, используя соединение в таблице

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

$insert=DB::table('tableA')->insert(DB::raw('SELECT ss.col1,ts.col2,ts.col3,ts.col4,ts.col5,
                5 AS col6 FROM 
                tableB AS ts
                 INNER JOIN tableC AS t ON ts.col2=t.id 
                 INNER JOIN tableD AS ss 
                 ON ts.col1=ss.col1 
                 AND ts.col3=ss.col3
                 AND ts.col4=ss.col4 
                 AND ts.col5=ss.col5
                 INNER JOIN tableE AS s 
                 ON ss.col1=s.id
                 WHERE t.status=1
                 AND s.status=1'));

Ошибка: Аргумент 1, переданный в Illuminate\Database\Query\Builder::insert(), должен иметь тип массива, заданный объект.

на самом деле он возвращает объект, где метод вставки ожидает массив. Я использовал необработанный запрос, он вставляет данные, но метка времени не заполняется, и он также не возвращает количество вставленных строк.

как я могу получить оба с помощью построителя запросов laravel ??


person hmamun    schedule 12.02.2018    source источник
comment
проблема, я думаю, заключается в том, что вы пытаетесь вставить значения, сгенерированные из соединения, и, следовательно, проблема ... вам нужно убедиться, что столбцы, которые вы пытаетесь добавить, должны соответствовать столбцам, определенным в таблице   -  person Dhaval Chheda    schedule 12.02.2018
comment
@DhavalChheda соответствует методу columns.insert, который ожидает массив, но значение, сгенерированное из объекта массива возврата соединения.   -  person hmamun    schedule 12.02.2018


Ответы (2)


Попробуй это. Это будет работать, если столбцы в tableA имеют те же имена, что и в вашем выборе:

$insert=DB::table('tableA')
->insert(json_decode(json_encode(DB::select('SELECT ss.col1,ts.col2,ts.col3,ts.col4,ts.col5,
                5 AS col6 FROM 
                tableB AS ts
                 INNER JOIN tableC AS t ON ts.col2=t.id 
                 INNER JOIN tableD AS ss 
                 ON ts.col1=ss.col1 
                 AND ts.col3=ss.col3
                 AND ts.col4=ss.col4 
                 AND ts.col5=ss.col5
                 INNER JOIN tableE AS s 
                 ON ss.col1=s.id
                 WHERE t.status=1
                 AND s.status=1')),true));
person vpalade    schedule 12.02.2018
comment
Столбцы created_at и updated_at не заполняются. На самом деле мне нужно количество вставленных строк и отметка времени. - person hmamun; 12.02.2018

Сначала вы можете сохранить результат первого запроса в переменной:

$data = DB::select('SELECT ss.col1,ts.col2,ts.col3,ts.col4,ts.col5,
    5 AS col6 FROM 
    tableB AS ts
    INNER JOIN tableC AS t ON ts.col2=t.id 
    INNER JOIN tableD AS ss 
    ON ts.col1=ss.col1 
    AND ts.col3=ss.col3
    AND ts.col4=ss.col4 
    AND ts.col5=ss.col5
    INNER JOIN tableE AS s 
    ON ss.col1=s.id
    WHERE t.status=1
    AND s.status=1');

Затем преобразуйте данные в массив:

$data = collect($data)->map(function($x){ return (array) $x; })->toArray();

И, наконец, вставьте его в БД, предположив, что столбцы совпадают.

$insert = DB::table('tableA')->insert($data);

РЕДАКТИРОВАТЬ

Вы можете использовать этот код, чтобы передать значения для timestamps полей, предполагая, что эти два поля находятся в конце спецификации таблицы, гарантируя, что столбцы совпадают со значениями:

$data = collect($data)->map(function($x){ 
    return array_push((array) $x, date('Y-m-d H:i:s'), date('Y-m-d H:i:s'));
})->toArray();
person Yulio Aleman Jimenez    schedule 12.02.2018
comment
Столбцы @Jimenez created_at и updated_at не заполняются. - person hmamun; 12.02.2018