簡體   English   中英

創建存儲過程以將新行插入表中

[英]Creating stored procedure to insert new rows into a table

我正在嘗試創建一個滿足以下問題的存儲過程,

編寫一個名為 event_registration 的存儲過程,用於處理參與者的事件條目。 當參與者注冊活動時,他們還可以選擇創建或加入群組。

您的過程必須采用四個輸入參數:

  • 參加人數
  • 展覽日期
  • 事件類型描述
  • 團隊名字。

該程序必須:

  • 檢查輸入的展覽日期和活動名稱是否有效
  • 檢查參與者是否想創建/加入一個組(即他們提供一個組名),如果提供,輸入展覽的組名是否存在:
    • 如果該組不存在,則程序應添加一個新組並將該參與者指定為組長,或者
    • 如果組存在,則程序應將參與者添加到現有組中

所以下面是我的表格:

CREATE TABLE group 
(
    group_id         NUMBER(3) NOT NULL,
    group_name       VARCHAR2(30) NOT NULL,
    exhibition_date  DATE NOT NULL,
    group_no_members NUMBER(2) NOT NULL,
    event_id         NUMBER(6) NOT NULL,
    entry_no         NUMBER(5) NOT NULL,
    char_id          NUMBER(3)
);

CREATE TABLE event 
(
    event_id         NUMBER(6) NOT NULL,
    exhibition_date  DATE NOT NULL,
    eventtype_code   CHAR(3) NOT NULL,
    event_starttime  DATE NOT NULL
);

CREATE TABLE eventtype 
(
    eventtype_code CHAR(3) NOT NULL,
    eventtype_desc VARCHAR2(50) NOT NULL
);

CREATE TABLE exhibition 
(
    exhibition_date     DATE NOT NULL,
    exhibition_name     VARCHAR2(50) NOT NULL,
    exhibition_director VARCHAR2(50) NOT NULL,
    exhibition_location VARCHAR2(50) NOT NULL
);

CREATE TABLE entry 
(
    event_id         NUMBER(6) NOT NULL,
    entry_no         NUMBER(5) NOT NULL,
    entry_starttime  DATE,
    entry_finishtime DATE,
    part_no          NUMBER(5) NOT NULL,
    group_id         NUMBER(3),
    char_id          NUMBER(3)
);

這是我的程序:

CREATE OR REPLACE PROCEDURE event_registration 
    (new_part_no IN NUMBER, 
     new_exhibition_date IN DATE, 
     new_eventtype_desc IN VARCHAR2, 
     new_group_name IN VARCHAR2, 
     output OUT VARCHAR2) 
AS
    exhibition_date_and_event_found NUMBER; group_found NUMBER;
BEGIN
    SELECT COUNT(*) 
    INTO exhibition_date_and_event_found 
    FROM event 
    NATURAL JOIN eventtype 
    WHERE exhibition_date = new_exhibition_date 
      AND eventtype_desc = new_eventtype_desc;
IF (exhibition_date_and_event_found = 0) THEN 
output := 'Invalid exhibition date/This exhibition does not have this event type';
ELSE
    IF(new_group_name != NULL) THEN
        SELECT COUNT(*) INTO group_found FROM group NATURAL JOIN exhibition WHERE group_name = new_group_name AND exhibition_date = new_exhibition_date;
        IF(group_found = 0) THEN
        INSERT INTO group VALUES ((SELECT COUNT(*)+1 FROM group), new_group_name, TO_DATE(new_exhibition_date, 'DD/MM/YYYY'), 1, (SELECT event_id FROM event NATURAL JOIN eventtype WHERE eventtype_desc = new_eventtype_desc AND exhibition_date = TO_DATE(new_exhibition_date,'DD/MM/YYYY')), (SELECT MAX(entry_no)+1 FROM entry WHERE event_id = (SELECT event_id FROM event NATURAL JOIN eventtype WHERE eventtype_desc = new_eventtype_desc AND exhibition_date = TO_DATE(new_exhibition_date, 'DD/MM/YYYY'))), NULL);
        INSERT INTO entry VALUES ((SELECT event_id FROM event NATURAL JOIN eventtype WHERE eventtype_desc = new_eventtype_desc AND exhibition_date = TO_DATE(new_exhibition_date, 'DD/MM/YYYY')), (SELECT MAX(entry_no)+1 FROM entry WHERE event_id = (SELECT event_id FROM event NATURAL JOIN eventtype WHERE eventtype_desc = new_eventtype_desc AND exhibition_date = TO_DATE(new_exhibition_date, 'DD/MM/YYYY'))), NULL, NULL, new_part_no, (SELECT group_id FROM group WHERE group_name = new_group_name), NULL);
        ELSE --group already exist 
        --update the group member number by 1 
        UPDATE group
        SET group_no_members = group_no_members + 1
        WHERE group_name = new_group_name;
        INSERT INTO entry VALUES ((SELECT event_id FROM event NATURAL JOIN eventtype WHERE eventtype_desc = new_eventtype_desc AND exhibition_date = TO_DATE(new_exhibition_date, 'DD/MM/YYYY')), (SELECT MAX(entry_no)+1 FROM entry WHERE event_id = (SELECT event_id FROM event NATURAL JOIN eventtype WHERE eventtype_desc = new_eventtype_desc AND exhibition_date = TO_DATE(new_exhibition_date, 'DD/MM/YYYY'))), NULL, NULL, new_part_no, (SELECT group_id FROM group WHERE group_name = new_group_name), NULL);
        END IF;
    ELSE
        INSERT INTO entry VALUES ((SELECT event_id FROM event NATURAL JOIN eventtype WHERE eventtype_desc = new_eventtype_desc AND exhibition_date = TO_DATE(new_exhibition_date, 'DD/MM/YYYY')), (SELECT MAX(entry_no)+1 FROM entry WHERE event_id = (SELECT event_id FROM event NATURAL JOIN eventtype WHERE eventtype_desc = new_eventtype_desc AND exhibition_date = TO_DATE(new_exhibition_date, 'DD/MM/YYYY'))), NULL, NULL, new_part_no, NULL, NULL);
    END IF;
END IF;
END;
/

該過程尚未完成,但我認為它足以編譯,但是當我運行它時,它會給出如下錯誤

Procedure EVENT_REGISTRATION compiled

LINE/COL  ERROR
--------- -------------------------------------------------------------
12/9      PL/SQL: SQL Statement ignored
12/21     PL/SQL: ORA-00947: not enough values
18/9      PL/SQL: SQL Statement ignored
18/21     PL/SQL: ORA-00947: not enough values
21/9      PL/SQL: SQL Statement ignored
21/21     PL/SQL: ORA-00947: not enough values
Errors: check compiler log

有人可以幫我嗎? 先感謝您!

  1. 對表使用約束(主鍵、外鍵等)。

  2. 對主鍵值使用序列(切勿使用SELECT COUNT(*) + 1 FROM ...來生成 id,因為您可能會在並行系統上獲得重復項)。

  3. 如果您使用約束,則無需檢查展覽日期和事件(展覽?)名稱是否正確,因為如果不正確,當您嘗試反對不存在的關系時,約束將引發異常。

  4. 切勿使用INSERT INTO table_name VALUES (...) ,您應該始終明確命名要插入的列:

     INSERT INTO table_name (col1, col2, col3) VALUES (value1, value2, value3);
  5. 不要一遍又一遍地使用相同的查詢來查找event_id 找到它一次並將其存儲在 PL/SQL 變量中,然后下次使用 PL/SQL 變量。

  6. GROUP保留字 不要將其用作標識符。

  7. 您不能使用value != NULL將值與NULL進行比較,因為NULL永遠不會等於或不等於其他任何值; 你需要使用value IS NOT NULL

  8. 確保您的表中沒有循環引用約束(即GROUP有一個entry_no引用entry表,而entry表有一個group_id列引用GROUP表。您不需要兩者,並且當您將約束放入然后你會得到一個循環。)


就像是:

CREATE TABLE exhibition 
(
    exhibition_date     DATE
                        PRIMARY KEY
                        NOT NULL,
    exhibition_name     VARCHAR2(50)
                        NOT NULL,
    exhibition_director VARCHAR2(50)
                        NOT NULL,
    exhibition_location VARCHAR2(50)
                        NOT NULL
);

CREATE TABLE eventtype 
(
    eventtype_code CHAR(3)
                   PRIMARY KEY
                   NOT NULL,
    eventtype_desc VARCHAR2(50)
                   NOT NULL
);

CREATE TABLE event 
(
    event_id         NUMBER(6)
                     NOT NULL
                     PRIMARY KEY,
    exhibition_date  REFERENCES exhibition(exhibition_date)
                     NOT NULL,
    eventtype_code   REFERENCES eventtype(eventtype_code)
                     NOT NULL,
    event_starttime  DATE
                     NOT NULL
);

CREATE TABLE "GROUP"
(
    group_id         NUMBER(3)
                     NOT NULL
                     PRIMARY KEY,
    group_name       VARCHAR2(30)
                     UNIQUE
                     NOT NULL,
    group_no_members NUMBER(2)
                     NOT NULL,
    event_id         REFERENCES event(event_id)
                     NOT NULL,
    char_id          NUMBER(3)
);

CREATE TABLE entry 
(
    event_id         REFERENCES event(event_id)
                     NOT NULL,
    entry_no         NUMBER(5)
                     PRIMARY KEY
                     NOT NULL,
    entry_starttime  DATE,
    entry_finishtime DATE,
    part_no          NUMBER(5)
                     NOT NULL,
    group_id         NUMBER(3)
                     REFERENCES "GROUP"(group_id),
    char_id          NUMBER(3)
);

然后:

CREATE SEQUENCE group_seq;
CREATE SEQUENCE entry_seq;

然后:

CREATE OR REPLACE PROCEDURE event_registration 
    (new_part_no IN NUMBER, 
     new_exhibition_date IN DATE, 
     new_eventtype_desc IN VARCHAR2, 
     new_group_name IN VARCHAR2, 
     output OUT VARCHAR2) 
AS
  v_event_id EVENT.EVENT_ID%TYPE;
  v_group_id "GROUP".GROUP_ID%TYPE;
BEGIN
  SELECT e.event_id
  INTO   v_event_id
  FROM   event e
         INNER JOIN eventtype et
         ON (e.eventtype_code = et.eventtype_code)
  WHERE  exhibition_date = new_exhibition_date
  AND    eventtype_desc  = new_eventtype_desc;

  IF new_group_name IS NOT NULL THEN
    MERGE INTO "GROUP" g
    USING DUAL
    ON (g.group_name = new_group_name)
    WHEN MATCHED THEN
      UPDATE
      SET group_no_members = group_no_members + 1
    WHEN NOT MATCHED THEN
      INSERT (
        group_id,
        group_name,
        group_no_members,
        event_id,
        char_id
      ) VALUES (
        GROUP_SEQ.NEXTVAL,
        new_group_name,
        1,
        v_event_id,
        NULL
      );
      
    SELECT group_id
    INTO   v_group_id
    FROM   "GROUP"
    WHERE  group_name = new_group_name;
  END IF;
        
  INSERT INTO entry (
    event_id,
    entry_no,
    entry_starttime,
    entry_finishtime,
    part_no,
    group_id,
    char_id
  )VALUES (
    v_event_id,
    entry_seq.NEXTVAL,
    NULL,
    NULL,
    new_part_no,
    v_group_id,
    NULL
  );
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    output := 'Invalid exhibition date/This exhibition does not have this event type';
END;
/

db<> 在這里擺弄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM