oracle GETTING THIS [错误]执行(25:14):ORA-00984:当尝试插入时,此处不允许列

vshtjzan  于 2022-11-03  发布在  Oracle
关注(0)|答案(2)|浏览(137)

这是我创建的表:

CREATE TABLE personal_info (
  Person_name VARCHAR(30) NOT NULL,
  Date_of_Birth DATE,
  Join_date DATE,
  Join_year NUMBER,
  Person_address VARCHAR(75),
  Person_Post VARCHAR(15),
  Person_id VARCHAR(9) NOT NULL UNIQUE,
  Email_primary VARCHAR(30),
  Phone_primary NUMBER,
  Email_secondary VARCHAR(30),
  Phone_secondary NUMBER,

  Sal_grade CHAR(1) NOT NULL,
  Empl_id NUMBER NOT NULL,
  CONSTRAINT FK_Salary_Person FOREIGN KEY (Sal_grade) REFERENCES salary(Salary_grade) ON DELETE CASCADE,
  CONSTRAINT FK_Employee_Person FOREIGN KEY (Empl_id) REFERENCES employee(Employee_id) ON DELETE CASCADE,

  CONSTRAINT UC_Person_ID UNIQUE (Empl_id,Person_name)
);

以下是员工表:

CREATE TABLE employee (
  Employee_id NUMBER NOT NULL PRIMARY KEY,
  Employee_job_description VARCHAR(200),
  Proj_id NUMBER NOT NULL,
  Dep_id NUMBER NOT NULL
);

ALTER TABLE employee
ADD CONSTRAINT FK_project_employee 
FOREIGN KEY (Proj_id) REFERENCES PROJECTS(Project_id) ON DELETE CASCADE;

ALTER TABLE employee
ADD CONSTRAINT FK_dept_employee 
FOREIGN KEY (Dep_id) REFERENCES dept(Dept_id) ON DELETE CASCADE;

CREATE SEQUENCE EMPID_SEQ1
MINVALUE 1
MAXVALUE 9999999
START WITH 10000
INCREMENT BY 4
CACHE 20;

我已经插入到雇员表中,没有问题。

INSERT INTO employee (Employee_id, Employee_job_description, Proj_id, Dep_id) VALUES(EMPID_SEQ1.NEXTVAL,'SENIOR VICE PRESIDENT',501,1);

但是当我尝试插入到PERSONAL_INFO表中时:

/* Formatted on 19-Oct-22 11:58:19 AM (QP5 v5.256.13226.35538) */
INSERT INTO PERSONAL_INFO (Empl_id,
                           Person_name,
                           Date_of_Birth,
                           Join_date,
                           Join_year,
                           Person_address,
                           Sal_grade,
                           Actual_salary,
                           Person_Post,
                           PERSON_ID,
                           Email_primary,
                           Phone_primary,
                           Email_secondary,
                           Phone_secondary)
     VALUES (EMPID_SEQ1.CURRVAL,
             'Mr. FF',
             TO_DATE ('1980/05/03 21:02:44', 'yyyy/mm/dd hh24:mi:ss'),
             TO_DATE ('2000/05/03 21:02:44', 'yyyy/mm/dd hh24:mi:ss'),
             TO_CHAR (Join_DATE, 'YYYY'),
             'Banani,Dhaka.',
             'D',
             150000,
             'SVP',
             TO_CHAR(TO_CHAR(Join_YEAR) || TO_CHAR (EMPID_SEQ1.CURRVAL)),
             'FF@bank.com',
             01234567891,
             'FFF@bank.com',
             99998882222);

我在插入PERSON_ID唯一关键字值时遇到了上述错误。基本上我希望PERSON_ID看起来像“200710016”。加入年份后面跟雇员ID。
但它告诉我这里不允许使用JOIN_YEAR列。

v8wbuo2f

v8wbuo2f1#

您不能引用刚插入的列-您必须再次“重复”相同的数据。
此外,还应该修改目标表(两种数据类型--电话号码不是真正的“数字”,因为可能有前导零;缺少一列)。
在序列中,您必须首先选择nextval,然后选择currval,因为最初currval不存在。
修复后:

SQL> CREATE TABLE personal_info
  2  (
  3     Person_name       VARCHAR (30) NOT NULL,
  4     Date_of_Birth     DATE,
  5     Join_date         DATE,
  6     Join_year         NUMBER,
  7     Person_address    VARCHAR (75),
  8     Person_Post       VARCHAR (15),
  9     Person_id         VARCHAR (9) NOT NULL UNIQUE,
 10     Email_primary     VARCHAR (30),
 11     Phone_primary     VARCHAR (30),         --> change datatype
 12     Email_secondary   VARCHAR (30),
 13     Phone_secondary   VARCHAR (30),         --> change datatype
 14     Sal_grade         CHAR (1) NOT NULL,
 15     Empl_id           NUMBER NOT NULL,
 16     actual_salary     NUMBER                --> add this column
 17  );

Table created.

插入:

SQL> INSERT INTO PERSONAL_INFO (Empl_id,
  2                             Person_name,
  3                             Date_of_Birth,
  4                             Join_date,
  5                             Join_year,
  6                             Person_address,
  7                             Sal_grade,
  8                             Actual_salary,
  9                             Person_Post,
 10                             PERSON_ID,
 11                             Email_primary,
 12                             Phone_primary,
 13                             Email_secondary,
 14                             Phone_secondary)
 15          VALUES (
 16                    EMPID_SEQ1.nextval,
 17                    'Mr. FF',
 18                    TO_DATE ('1980/05/03 21:02:44', 'yyyy/mm/dd hh24:mi:ss'),
 19                    TO_DATE ('2000/05/03 21:02:44', 'yyyy/mm/dd hh24:mi:ss'),
 20                    TO_CHAR (
 21                       TO_DATE ('2000/05/03 21:02:44', 'yyyy/mm/dd hh24:mi:ss'),
 22                       'YYYY'),
 23                    'Banani,Dhaka.',
 24                    'D',
 25                    150000,
 26                    'SVP',
 27                    TO_CHAR (
 28                          TO_CHAR (
 29                             TO_DATE ('2000/05/03 21:02:44',
 30                                      'yyyy/mm/dd hh24:mi:ss'),
 31                             'YYYY')
 32                       || TO_CHAR (EMPID_SEQ1.CURRVAL)),
 33                    'FF@bank.com',
 34                    '01234567891',
 35                    'FFF@bank.com',
 36                    '99998882222');

1 row created.
6jygbczu

6jygbczu2#

表中不应有join_year列,因为该值可以从join_date列计算出来,如果它是独立的,则两列可能会不同步。如果确实要在表中有它,则它应该是虚拟列。对于person_id也是如此(尽管如果出于业务原因需要持久保存person_id以便以后可以对其进行更改,那么可以使用BEFORE INSERT触发器而不是使用虚拟列来设置它,但无论采用哪种方式,都不需要在INSERT语句中提供从其他列派生的缺省值):

CREATE TABLE personal_info (
  Person_name     VARCHAR(30) NOT NULL,
  Date_of_Birth   DATE,
  Join_date       DATE,
  Join_year       NUMBER
                  GENERATED ALWAYS AS (EXTRACT(YEAR FROM join_date)),
  Person_address  VARCHAR(75),
  Person_Post     VARCHAR(15),
  Person_id       VARCHAR(9)
                  GENERATED ALWAYS AS (
                    CAST(
                      TO_CHAR(EXTRACT(YEAR FROM join_date), 'FM0000')
                      || TO_CHAR(empl_id, 'FM00000')
                      AS VARCHAR2(9)
                    )
                  )
                  NOT NULL
                  UNIQUE,
  Email_primary   VARCHAR(30),
  Phone_primary   VARCHAR2(12),
  Email_secondary VARCHAR(30),
  Phone_secondary VARCHAR2(12),
  Sal_grade       /* CHAR(1) */ NOT NULL,
  Actual_Salary   NUMBER(10,2),
  Empl_id         /* NUMBER */ NOT NULL,
  CONSTRAINT FK_Salary_Person FOREIGN KEY (Sal_grade)
    REFERENCES salary(Salary_grade) ON DELETE CASCADE,
  CONSTRAINT FK_Employee_Person FOREIGN KEY (Empl_id)
    REFERENCES employee(Employee_id) ON DELETE CASCADE,
  CONSTRAINT UC_Person_ID UNIQUE (Empl_id, Person_name)
);
  • 注意:如果列具有外键约束,则不需要包括数据类型;如果省略它,则列将采用与它所引用的主键/唯一键相同的数据类型,这样就可以确保表之间的一致性。*
  • 注二:EMPID_SEQ1序列从10000开始,按4递增,最大值为9999999,Person_id列可以包含9个字符,其中4个是年份,因此一旦表中有22500人并且序列达到100000,那么对于Person_id列来说,它将太大。您可能应该将序列限制为99999,或者将Person_id列设置得更大。*
  • 注意3:虽然电话号码是数字,但它们通常有前导零,这些数字不会存储在NUMBER列中,因此您应该将电话号码存储为VARCHAR2。*
  • 注意4:您缺少actual_salary列。*

然后您可以用途:

INSERT INTO PERSONAL_INFO (
  Empl_id,
  Person_name,
  Date_of_Birth,
  Join_date,
  Person_address,
  Sal_grade,
  Actual_salary,
  Person_Post,
  Email_primary,
  Phone_primary,
  Email_secondary,
  Phone_secondary
) VALUES (
  EMPID_SEQ1.CURRVAL,
  'Mr. FF',
  TO_DATE ('1980/05/03 21:02:44', 'yyyy/mm/dd hh24:mi:ss'),
  TO_DATE ('2000/05/03 21:02:44', 'yyyy/mm/dd hh24:mi:ss'),
  'Banani,Dhaka.',
  'D',
  150000,
  'SVP',
  'FF@bank.com',
  '01234567891',
  'FFF@bank.com',
  '99998882222'
);

fiddle

相关问题