0

次のデータ モデルを持つ PostGreSQL データベースがあります。

CREATE TABLE staff (s_id serial UNIQUE, name, username, password, email)
CREATE TABLE institution (i_id serial UNIQUE, name);
CREATE TABLE isStaffOf (i_id, s_id); //foreign key references

ユーザーがフォームを送信すると、最初の 2 つのデータ テーブルに情報を書き込み、s_id と i_id の値を自動的に生成する PHP スクリプトがあります。すごい!

システムが s_id と i_id の両方を isStaffOf リレーションに書き込むようにするためにいくつかの PHP の変更を試してみました。PHPコードについては、以下を参照してください。

    $name = $_POST["name"];
    $username = $_POST["username"];
    $password = $_POST["password"];
    $email = $_POST["email"];
    $institution = $_POST["institution"];

    $conn = pg_connect("host=***** port=**** dbname=****** user=**** password=******");
    $staffWrite = pg_query("INSERT INTO staff(name, username, password, email) VALUES ('$name', '$username', '$password', '$email')");
    $instiWrite = pg_query("INSERT INTO institution(name) VALUES ('$institution')");

    $instiFK=pg_query("SELECT i_id FROM institution WHERE name='$institution'");
    $staffFK=pg_query("SELECT s_id FROM staff WHERE name='$username'");

    $sql=("INSERT INTO isstaffof(i_id, s_id) VALUES ('$instiFK', '$staffFK')");
    $result = pg_query($sql);

それは私が現時点で持っているスクリプトですが、機能していません。これを修正して、ユーザーがすべてのデータ テーブルを送信すると、データ テーブルがいっぱいになり、参照整合性が適用されるようにする方法についてのアイデアはありますか? 私はほとんどそこにいて、まだ物事を試していますが、役に立ちません。

エラーメッセージ:

 ERROR: invalid input syntax for integer: "Resource id #4" LINE 1: INSERT INTO isstaffof(i_id, s_id) VALUES ('Resource id #4', ...

さらに説明が必要な場合はお知らせください。しかし、私が達成したいことは明確であり、多くのpg_query電話をかけなくても達成できると確信しています。

4

3 に答える 3

1

PostgreSQLバージョン9.1以降、単一のクエリを使用して3つのテーブルすべてにINSERTを実行できます。これは、書き込み可能な共通テーブル式です。

WITH 
step_1 AS(
    INSERT INTO staff (name) VALUES('Frank') RETURNING s_id
),
step_2 AS (
    INSERT INTO institution (name) VALUES('PostgreSQL') RETURNING i_id
)
INSERT INTO isStaffOf (i_id, s_id) SELECT i_id,s_id FROM step_1, step_2;

シンプル、高速、信頼性。

いくつかのレコードがすでに存在し、主キー値を選択したい場合は、他のトリックを実行することもできます。

于 2012-09-06T07:53:32.963 に答える
0

pg_fetch_assocなどで結果を取得する必要があります。現在使用している方法では、pg_query リソース全体を整数として渡しています。明らかに、php はそれを有効な整数に変換できません。

$name = $_POST["name"];
$username = $_POST["username"];
$password = $_POST["password"];
$email = $_POST["email"];
$institution = $_POST["institution"];

$conn = pg_connect("host=***** port=**** dbname=****** user=**** password=******");
$staffWrite = pg_query("INSERT INTO staff(name, username, password, email) VALUES ('$name', '$username', '$password', '$email')");
$instiWrite = pg_query("INSERT INTO institution(name) VALUES ('$institution')");

$instiFK=pg_query("SELECT i_id FROM institution WHERE name='$institution'");
$rowInsti = pg_fetch_assoc($instiFK);
$staffFK = pg_query("SELECT s_id FROM staff WHERE name='$username'");
$rowStaff = pg_fetch_assoc($staffFK);

$result = pg_query("INSERT INTO isstaffof(i_id, s_id) VALUES (".$rowInsti['i_id'].", ".$rowStaff['s_id'].")");    

別の方法として、すべての挿入の直後にpg_last_oidを使用して ID を取得することもできます。(RETURNING ソリューションはさらに美しいでしょう。php.net ページのコメントを読んでください)

于 2012-09-05T13:50:32.263 に答える
0

isstaffof テーブルを作成するときは、少なくともデータ型を指定する必要があり、それらが外部キーであることを指定できます。

CREATE TABLE isstaffof
    (i_id BIGINT REFERENCES institution(i_id)
    , s_id BIGINT REFERENCES staff(s_id)
    );

注: 識別子に MixedCase を使用しないでください。別の DBMS プラットフォームに移植する必要がある場合は、ひどい問題が発生する可能性があります。

INSERT INTO ... SELECT ... FROM ...更新: 単純なステートメントに入れるだけです。

CREATE TABLE staff (s_id serial UNIQUE, sname varchar);
CREATE TABLE institution (i_id serial UNIQUE, iname varchar);
CREATE TABLE isstaffof
    (i_id BIGINT REFERENCES institution(i_id)
    , s_id BIGINT REFERENCES staff(s_id)
    );

INSERT INTO isstaffof(i_id,s_id)
SELECT i.i_id,s.s_id
FROM staff s, institution i
WHERE i.iname='$institution'
AND s.sname = '$staff'
        ;

これで、それをフロントエンド コードにラップできます。

于 2012-09-05T14:01:45.770 に答える