First, the multi-table update
For example, there is a line of a module system due to the abnormal, leading to overall system data error has occurred, you need to manually rewrite the database error, Oracle update statement updates the values from another table
update basic grammar format
UPDATE TABLE_NAME SET COLUMN1 = VALUE1 WHERE COLUMN2 = VALUE2
First, create the following two tables, so that the table is named GF_CONS_TRAN_TEST AS A
-- ---------------------------- -- Table structure for GF_CONS_TRAN_TEST -- ---------------------------- CREATE TABLE GF_CONS_TRAN_TEST ( "ID" VARCHAR2(64 BYTE) NOT NULL , "USERNAME" VARCHAR2(255 BYTE) NULL , "PASSWORD" VARCHAR2(255 BYTE) NULL , "CREATEDATE" DATE NULL , "PHONE" VARCHAR2(255 BYTE) NULL ) LOGGING NOCOMPRESS NOCACHE ; -- ---------------------------- -- Records of GF_CONS_TRAN_TEST -- ---------------------------- INSERT INTO GF_CONS_TRAN_TEST VALUES ( '0001', 'national network of Jinzhou New Area', '123445', TO_DATE ( '2019-11-29 10:25:23', 'YYYY-MM-DD HH24: MI: SS'), null); INSERT INTO GF_CONS_TRAN_TEST VALUES ( '0002', 'Dalian power company', 'phhs_all', TO_DATE ( '2019-11-18 10:25:59', 'YYYY-MM-DD HH24: MI: SS'), null) ; INSERT INTO GF_CONS_TRAN_TEST VALUES ( '0003', 'Zhongshan power company', 'zs_phs', TO_DATE ( '2019-11-29 10:26:49', 'YYYY-MM-DD HH24: MI: SS'), null) ; -- ---------------------------- -- Indexes structure for table GF_CONS_TRAN_TEST -- ---------------------------- -- ---------------------------- -- Checks structure for table GF_CONS_TRAN_TEST -- ---------------------------- ALTER TABLE GF_CONS_TRAN_TEST ADD CHECK ("ID" IS NOT NULL); -- ---------------------------- -- Primary Key structure for table GF_CONS_TRAN_TEST -- ---------------------------- ALTER TABLE GF_CONS_TRAN_TEST ADD PRIMARY KEY ("ID");
A table structure and data was as follows:
And then create a structure similar to Table A Table B, GF_CONS_TRAN_TEST_COPY AS B
-- ---------------------------- -- Table structure for GF_CONS_TRAN_TEST_COPY -- ---------------------------- CREATE TABLE GF_CONS_TRAN_TEST_COPY ( "ID" VARCHAR2(64 BYTE) NOT NULL , "USERNAME" VARCHAR2(255 BYTE) NULL , "PASSWORD" VARCHAR2(255 BYTE) NULL , "CREATEDATE" DATE NULL ) LOGGING NOCOMPRESS NOCACHE ; -- ---------------------------- -- Records of GF_CONS_TRAN_TEST_COPY -- ---------------------------- INSERT INTO GF_CONS_TRAN_TEST_COPY VALUES ( '0001', 'national network of Jinzhou New Area _ updates', '123445', null); INSERT INTO GF_CONS_TRAN_TEST_COPY VALUES ( '0003', '_ Update Zhongshan power company', 'zs_phs', null); -- ---------------------------- -- Indexes structure for table GF_CONS_TRAN_TEST_COPY -- ---------------------------- -- ---------------------------- -- Checks structure for table GF_CONS_TRAN_TEST_COPY -- ---------------------------- ALTER TABLE "USER_PSSC"."GF_CONS_TRAN_TEST_COPY" ADD CHECK ("ID" IS NOT NULL); -- ---------------------------- -- Primary Key structure for table GF_CONS_TRAN_TEST_COPY -- ---------------------------- ALTER TABLE GF_CONS_TRAN_TEST_COPY ADD PRIMARY KEY ("ID");
Structure and Data Table B below
It can be seen that the first table (GF_CONS_TRAN_TEST AS A) has three data, the second table (GF_CONS_TRAN_TEST_COPY AS B) has two data fields have the same ID , (or else there is no update condition), assumed here to update a table USENAME listed in table B data, because there is a unique primary key ID indexing, we can write
UPDATE GF_CONS_TRAN_TEST A SET A.USERNAME = ( SELECT B.USERNAME FROM GF_CONS_TRAN_TEST_COPY B WHERE A.ID = B.ID )
The results show that the update is successful, but the affected line is the 3 -line, we look at the table after the A update data
Table B since no records 0002 , just as with the statement WHERE A.ID = B.ID so Table A data to update all table B are not shown as empty, so that not the whole data before , but the boss did not say that, ah,
Fortunately, Oracle database when we insert, update, delete, etc., prone to misuse, leading to other content database is modified by an ordinary sql statement can not be reverted, can be Oracle Flashback database table mechanism, according to the time stamp,
Second, the reduction table
1. Are the first query this point in time the data you want to restore data
SELECT * FROM TABLENAME AS OF TIMESTAMP TO_TIMESTAMP ( '2019-07-05 08:50:00', 'YYYY-MM-DD HH24:MI:SS' ) - Data Table certain time period
Raw data we can see the data for the previous update
2. open flashback mechanism this table
ALTER TABLE TABLE_NAME ENABLE ROW MOVEMENT
3. state flash back to the table this time
FLASHBACK TABLE TABLE_NAME TO TIMESTAMP TO_TIMESTAMP('2019-11-29 11:00:00','YYYY-MM-DD HH24:MI:SS')
4. Close this table flashback state (Do not forget to perform this step)
ALTER TABLE TABLE_NAME DISABLE ROW MOVEMENT
Finished'll find table A data has been restored to its state prior to this time, because before you write the update statement updates all records, so we add a restriction, when the B table records the primary key ID in Table A start there in update, SQL statement is as follows:
UPDATE GF_CONS_TRAN_TEST A SET A.USERNAME = (SELECT B.USERNAME FROM GF_CONS_TRAN_TEST_COPY B WHERE A.ID = B.ID) WHERE EXISTS (SELECT 1 FROM GF_CONS_TRAN_TEST_COPY B WHERE B.ID = A.ID)
We can see this time update the two records, and we think exactly the same, back to Table A data
These two data we have just updated data and 0002 data has not changed, in line with the original requirements
Three, MERGE command
In oracle9g introduced MERGE command may be a sql on a table while statement insert and update operations, Merge command line to be selected from one or more data sources update or insert into one or more tables.
Merge into action is to solve the B table with the new A table data, if A table does not, put the B table data insertion A table or insert data into a table, if the table has the data is updated, if not then inserted.
Generally, we perform an insert statement like this
INSERT INTO GF_CONS_TRAN_TEST (ID, USERNAME, PASSWORD) VALUES ( '0004', 'national network Zhuanghe supply', 'zh_org')
当然对于主键ID来说常用的两种方式就是UUID和自增长了,很少会出现主键重复的问题,但是假如在插入数据的时候根据主键4判断,如果没有插入数据,如果有则根据ID来更新,岂不一举两得
为了可以看到效果,我们手动更新A表数据如下
B表数据不变
B表中有0001在A表中没有,0003在A表中存在,0002在B表中没有,如果没有出错应该是更新0003,插入0001,SQL执行如下:
MERGE INTO GF_CONS_TRAN_TEST A USING (SELECT B.ID, B.USERNAME, B.PASSWORD FROM GF_CONS_TRAN_TEST_COPY B ) C ON (A.ID = C.ID) WHEN MATCHED THEN UPDATE SET A.USERNAME = C.USERNAME, A.PASSWORD = C.PASSWORD WHEN NOT MATCHED THEN INSERT (A.ID, A.USERNAME, A.PASSWORD) VALUES(C.ID, C.USERNAME, C.PASSWORD)
执行结构如下:
与我们所想一致,一条为更新操作,一条为新增操作。