2017-04-08 99 views
2

我正在嘗試使用PostgreSQL數據庫在PHP中開發一個Q &網站。 我有一個動作來創建一個頁面,其中有一個標題,正文,類別和標籤。我設法插入所有這些字段,但我有一些問題插入多個標記值。將多個INSERTS合併到一個表中並使用多個表

我用這個函數來獲取逗號分隔值到一個數組中,現在我想要在表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); 
} 

我在想這樣做這樣的事情:

全球$康恩;

foreach ($tags as $tag) { 

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

但是,然後我需要標籤ID插入我多到許多表。我是否需要創建另一個程序,get_tags_id,然後獲取tag_id數組,然後在嘗試使用標記時插入它們? 我什麼時候執行查詢?在兩個插入之後或者在彼此之後?

對不起,任何誤用的術語或我的新手問題。我是PHP的新手,我正在努力應對一些新的概念。

+0

您需要在問題表和標籤表上有主鍵(ID)。然後製作第三張只包含問題和標籤ID的表格。 – miken32

+0

我擁有它。我省略了這個,因爲在我使用這種方法的問題上很清楚 –

+0

插入後,您可以使用PDO的lastInsertId函數檢索剛剛插入的行的主鍵。然後,您可以將數據添加到下一個表中,而不必執行單獨的查詢來首先獲取主鍵。 http://php.net/manual/en/pdo.lastinsertid.php –

回答

1

您可以在之間完成一個使用CTE的SQL命令。

假設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 here

這會創建任何尚未存在的標籤。

Postgres數組的文本表示形式如下所示:{tag1, tag2, tag3}

如果輸入數組保證具有不同的標籤,則可以從CTE input_tags中刪除DISTINCT

詳細解釋

如果你有併發寫入您可能需要做更多。特別考慮第二個環節。

相關問題