Несколько ВСТАВКИ в одну таблицу и много ко многим таблицам

Я пытаюсь разработать вопрос&Сайт на PHP, использующий базу данных PostgreSQL.
У меня есть действие, чтобы создать страницу, которая имеет заголовок, тело, категорию и теги. Мне удалось вставить все эти поля, но у меня возникли некоторые проблемы при вставке нескольких значений тегов.

Я использовал эту функцию, чтобы получить значения через запятую в массив, и теперь я хочу что-то, что вставляет каждый элемент массива в базу данных (избегая повторений) в таблице tags и после этого вставить в мою таблицу отношений многих ко многим questiontags:

$tags = explode(',', $_POST['tags']); //Comma separated values to an array

который печатает что-то вроде этого:

Array ( [0] => hello [1] => there [2] => this [3] => is [4] => a [5] => test )

Действие / create_question.php

$category = get_categoryID_by_name($_POST['category']);

$question = [
'userid' => auth_user('userid'),
'body' => $_POST['editor1'],
'title' => $_POST['title'],
'categoryid' => $category
];

create_question($question, $tags);

а потом мой create_question где я должен вставить теги.

function create_question($question, $tags) {

global $conn;
$query_publications=$conn->prepare("SELECT * FROM insert_into_questions(:body, :userid, :title, :categoryid);
");
$query_publications->execute($question);
}

Я думал о том, чтобы сделать что-то вроде этого:

глобальный $ conn;

foreach ($tags as $tag) {

$query_publications=$conn->prepare("INSERT INTO tags(name) VALUES($tag);
");
$query_publications->execute($question);
}

Но тогда мне понадобится идентификатор тега, чтобы вставить его в таблицу «многие ко многим». Нужно ли создавать еще одну процедуру, get_tags_id а затем получить tag_id массив и вставить их, как я пытался для тегов?
Когда мне выполнить запрос? После обеих вставок или в конце друг друга?

Извините за неверно использованный термин или за вопрос новичка. Я новичок в PHP, и я борюсь с некоторыми новыми концепциями.

3

Решение

Вы можете сделать все это в один Команда SQL с использованием CTE.

Предполагая Postgres 9,6 и эта классическая схема «многие ко многим» (поскольку вы ее не предоставили):

CREATE TABLE questions (
question_id serial PRIMARY KEY
, title text NOT NULL
, body text
, userid int
, categoryid int
);

CREATE TABLE tags (
tag_id serial PRIMARY KEY
, tag text NOT NULL UNIQUE);

CREATE TABLE questiontags (
question_id int REFERENCES questions
, tag_id      int REFERENCES tags
, PRIMARY KEY(question_id, tag_id)
);

Чтобы вставить не замужем вопрос с массив тегов:

WITH input_data(body, userid, title, categoryid, tags) AS (
VALUES (:title, :body, :userid, :tags)
)
, input_tags AS (                         -- fold duplicates
SELECT DISTINCT tag
FROM   input_data, unnest(tags::text[]) tag
)
, q AS (                                  -- insert question
INSERT INTO questions
(body, userid, title, categoryid)
SELECT body, userid, title, categoryid
FROM   input_data
RETURNING question_id
)
, t AS (                                  -- insert tags
INSERT INTO tags (tag)
TABLE  input_tags  -- short for: SELECT * FROM input_tags
ON     CONFLICT (tag) DO NOTHING        -- only new tags
RETURNING tag_id
)
INSERT INTO questiontags (question_id, tag_id)
SELECT q.question_id, t.tag_id
FROM   q, (
SELECT tag_id
FROM   t                                -- newly inserted
UNION  ALL
SELECT tag_id
FROM   input_tags JOIN tags USING (tag) -- pre-existing
) t;

dbfiddle Вот

Это создает любые теги, которые еще не существуют на лету.

Текстовое представление Массив Postgres выглядит так: {tag1, tag2, tag3},

Если входной массив гарантированно имеет различные теги, вы можете удалить DISTINCT из CTE input_tags,

детализированный объяснение:

Если у вас есть одновременные записи Возможно, вам придется сделать больше. Рассмотрим вторую ссылку в частности.

2

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

Других решений пока нет …