SQL堂上作业七

新行添加

传统添加

我们可以用INSERT命令进行行的添加,这样只能添加一行

INSERT INTO departments(department_id, department_name, 
manager_id, location_id)
VALUES (1070, 'Public Relations', 100, 1700);

输出为:已创建 1 行。

添加带空值的行

我们可以添加带空值的行

INSERT INTO departments (department_id, 
department_name )
VALUES (1030, 'Purchasing');

我们查询对应的值,输出如下:

DEPARTMENT_ID DEPARTMENT_NAME                                              MANAGER_ID LOCATION_ID
------------- ------------------------------------------------------------ ---------- -----------
         1030 Purchasing

我们也可以这样添加行

INSERT INTO departments
VALUES (1100, 'Finance', NULL, NULL);

效果与上文类似

添加日期相关的行

我们可以自动添加当前的日期

INSERT INTO employees (employee_id, 
                    first_name, last_name, 
                    email, phone_number,
                    hire_date, job_id, salary, 
                    commission_pct, manager_id,
                    department_id)
VALUES                (10113, 
                'Louis', 'Popp', 
                'LPOPPxfz', '515.124.4567', 
                SYSDATE, 'AC_ACCOUNT', 6900, 
                NULL, 205, 100);

我们也可以用TO_DATE函数构造日期

INSERT INTO employees
VALUES (10114, 
'Den', 'Raphealy', 
'DRAPHEALxfz', '515.127.4561',
TO_DATE('FEB 3, 1999', 'MON DD, YYYY'),
'AC_ACCOUNT', 11000, NULL, 100, 30);

我们输出下构造出的数值

EMPLOYEE_ID FIRST_NAME                               LAST_NAME                                          EMAIL                                              PHONE_NUMBER
                            HIRE_DATE    JOB_ID                   SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
----------- ---------------------------------------- -------------------------------------------------- -------------------------------------------------- ---------------------------------------- ------------ -------------------- ---------- -------------- ---------- -------------
      10114 Den                                      Raphealy                                           DRAPHEALxfz                                        515.127.4561
                            03-FEB-99    AC_ACCOUNT                11000                       100            30

行的复制

我们可以用SELECT子句来复制行,再用INSERT插入

INSERT INTO sales_reps(id, name, salary, commission_pct)
SELECT employee_id, last_name, salary, commission_pct
FROM employees
WHERE job_id LIKE '%REP%';

由于不存在表sales_reps,我们需要把这个表建出来

CREATE TABLE sales_reps
    ( id    NUMBER(6) 
    , name      VARCHAR2(25)
    , salary         NUMBER(8,2)
    , commission_pct NUMBER(2,2)
    , PRIMARY KEY (id)
    ) ;

然后再运行下面的代码,输出如下:

已创建 33 行。

我们可以select出来看下

        ID NAME                                                   SALARY COMMISSION_PCT
---------- -------------------------------------------------- ---------- --------------
       150 Tucker                                                  10000             .3
       151 Bernstein                                                9500            .25
       152 Hall                                                     9000            .25
       153 Olsen                                                    8000             .2
       154 Cambrault                                                7500             .2
       155 Tuvault                                                  7000            .15
       156 King                                                    10000            .35
       157 Sully                                                    9500            .35
       158 McEwen                                                   9000            .35
       159 Smith                                                    8000             .3
       160 Doran                                                    7500             .3
       161 Sewall                                                   7000            .25
       162 Vishney                                                 10500            .25
       163 Greene                                                   9500            .15
       164 Marvins                                                  7200             .1
       165 Lee                                                      6800             .1
       166 Ande                                                     6400             .1
       167 Banda                                                    6200             .1
       168 Ozer                                                    11500            .25
       169 Bloom                                                   10000             .2
       170 Fox                                                      9600             .2
       171 Smith                                                    7400            .15
       172 Bates                                                    7300            .15
       173 Kumar                                                    6100             .1
       174 Abel                                                    11000             .3
       175 Hutton                                                   8800            .25
       176 Taylor                                                   8600             .2
       177 Livingston                                               8400             .2
       178 Grant                                                    7000            .15
       179 Johnson                                                  6200             .1
       202 Fay                                                      6000
       203 Mavris                                                   6500
       204 Baer                                                    10000

已选择33行。

修改数值

我们可以用UPDATE命令对数值进行修改

UPDATE employees
SET department_id = 70
WHERE employee_id = 113;

我们的选定和输出如下:

已更新 1 行。

SQL> SELECT * FROM employees WHERE department_id = 113;

未选定行

SQL> SELECT * FROM employees WHERE department_id = 70;

EMPLOYEE_ID FIRST_NAME                               LAST_NAME
        EMAIL                                              PHONE_NUMBER
----------- ---------------------------------------- -------------------------------------------------- -------------------------------------------------- ----------------------------------------
HIRE_DATE      JOB_ID                   SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
-------------- -------------------- ---------- -------------- ---------- -------------
        113 Luis                                     Popp
        LPOPP                                              515.124.4567
07-12月-99     FI_ACCOUNT                 6900                       108            70

        204 Hermann                                  Baer
        HBAER                                              515.123.8888
07-6月 -94     PR_REP                    10000                       101            70


注意:如果你不增加WHERE限制,所有的数据都会被修改

UPDATE copy_emp
SET department_id = 110;

同时改两行

将employee_id=114的人的job_id和salary都改为和205的一样

UPDATE employees
SET job_id = (SELECT job_id 
FROM employees 
WHERE employee_id = 205), 
salary = (SELECT salary 
FROM employees 
WHERE employee_id = 205) 
WHERE employee_id = 114;

完成修改后,我们看下效果

SQL> SELECT job_id,salary FROM employees WHERE employee_id IN (114,205);

JOB_ID                   SALARY
-------------------- ----------
AC_MGR                    12000
AC_MGR                    12000

用基于其他表的查询子句修改该表

UPDATE copy_emp
SET department_id = (SELECT department_id
FROM employees
WHERE employee_id = 100)
WHERE job_id = (SELECT job_id
FROM employees
WHERE employee_id = 200);

一些错误的排查

我们输入下面的修改信息时,会出现一些错误

UPDATE employees
SET department_id = 55
WHERE department_id = 110;

会有以下报错信息

UPDATE employees
*
第 1 行出现错误:
ORA-02291: 违反完整约束条件 (SYS.EMP_DEPT_FK) - 未找到父项关键字

这是因为,55并不是department_id的合法值,把55改为60其实就可以了

行的删除

和UPDATE语句很相似

DELETE FROM departments
WHERE department_name = 'Finance';

结果是有一行被删除了

基于其他表的数据删除

DELETE FROM employees
WHERE department_id =
(SELECT department_id
FROM departments
WHERE department_name LIKE '%Public%');

默认语句

我们可以用DEFAULT来插入数据

INSERT INTO departments
(department_id, department_name, manager_id) 
VALUES (300, 'Engineering', DEFAULT);

也可以更新数据

UPDATE departments 
SET manager_id = DEFAULT WHERE department_id = 10;

表的合并

我们可以用MERGE命令来将两张表进行合并

注意:此处的“合并”,指的是将表A中的数据,以某种形式融入到表B中,但表A并不会消失。

此处有点难理解,我给个示例代码

MERGE INTO table_name alias1 
USING (table|view|sub_query) alias2
ON (join condition) 
WHEN MATCHED THEN 
    UPDATE  
    SET col1 = col1_val1, 
        col2 = col2_val2 
WHEN NOT MATCHED THEN 
    INSERT (column_list) VALUES (column_values); 

这里的含义是:向表table_name (别名alias1)中融入数据,融入的数据由(表table经过某个子查询产生,别名alias2)提供

join condition表示的是表合并的规则(比如说比较两者的id或者名字)

当比较条件相同是(WHEN MATCHED THEN),执行UPDATE SET下的一系列语句

当比较条件不同时(WHEN NOT NATCHED THEN),执行INSERT下的一系列语句。

下方提供一个例子

在这里插入图片描述

上图为表MERGE_SOURCE

在这里插入图片描述

上图为表MERGE_TARGET

建表和插入的命令如下:

CREATE TABLE MERGE_SOURCE(
	id NUMBER(6) ,
	name VARCHAR2(20),
	age NUMBER(6),
	PRIMARY KEY(id)
	);
	
INSERT INTO MERGE_SOURCE VALUES (1,'Amy',23);
INSERT INTO MERGE_SOURCE VALUES (2,'Coco',26);
INSERT INTO MERGE_SOURCE VALUES (3,'Helen',30);


CREATE TABLE MERGE_TARGET(
	id NUMBER(6),
	name VARCHAR2(20),
	age NUMBER(6),
	PRIMARY KEY(id)
	);
	
INSERT INTO MERGE_TARGET VALUES (1,'Amy',23);
INSERT INTO MERGE_TARGET VALUES (3,'Helen',30);
INSERT INTO MERGE_TARGET VALUES (4,'Emma',25);
INSERT INTO MERGE_TARGET VALUES (5,'Jane',21);

MERGE的命令如下:

MERGE into MERGE_TARGET TARGET
USING(SELECT * FROM MERGE_SOURCE) SOURCE
ON(TARGET.id=SOURCE.id)
WHEN MATCHED THEN
 UPDATE
 SET TARGET.NAME = SOURCE.NAME,
	 TARGET.AGE = SOURCE.AGE
WHEN NOT MATCHED THEN
 INSERT VALUES (SOURCE.ID,SOURCE.NAME,SOURCE.AGE);

输出如下:

SQL> SELECT * FROM MERGE_TARGET;

        ID NAME                                            AGE
---------- ---------------------------------------- ----------
         1 Amy                                              23
         3 Helen                                            30
         4 Emma                                             25
         5 Jane                                             21
         2 Coco                                             26

表的标记和回滚

我们可以给数据库标记一些保存点

做完一些修改后,如果我们觉得这些修改不妥,我们可以直接进行回滚。

拍摄保存点的命令如下:

SAVEPOINT update_done;

中间我们可以执行一系列的操作,回滚的命令如下:

ROLLBACK TO update_done;

其中update_done是一个保存点的名字,可以随意命名。

当然,我们可以拍一些不带名字的点,比如说COMMIT和ROLLBACK。

posted @ 2022-11-05 12:29  AlphaInf  阅读(81)  评论(3编辑  收藏  举报