일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 머신러닝기초
- 프록시배포구조
- git rebase
- ethers typescript
- 스마트컨트렉트 예약어 함수이름 중복
- Vue
- 러스트 기초
- nest.js설명
- 러스트기초
- 러스트 기초 학습
- chainlink 설명
- ambiguous function description
- 깃허브명령어
- ethers
- 스마트 컨트렉트 함수이름 중복
- 체인의정석
- Vue.js
- ethers websocket
- vue기초
- 스마트컨트렉트프록시
- nestjs 튜토리얼
- 컨트렉트 동일한 함수이름 호출
- ethers v6
- rust 기초
- 컨트렉트 배포 자동화
- multicall
- 스마트컨트렉트 함수이름 중복 호출
- SBT표준
- ethers type
- 스마트컨트렉트테스트
- Today
- Total
체인의정석
MYSQL에서 Insert와 update 하나의 구문으로 처리하기 (ON DUPLICATE KEY UPDATE, UPSERT, sequalize) 본문
MYSQL에서 Insert와 update 하나의 구문으로 처리하기 (ON DUPLICATE KEY UPDATE, UPSERT, sequalize)
체인의정석 2023. 8. 21. 15:11현재 데이터의 상태를 업데이트 하는 쿼리를 만들다가 데이터가 있는지 DB접근 1 번 그리고 데이터가 없다면 삽입 있다면 업데이트를 하는 로직을 따로 만들었다.
그러나 이를 한번에 할 수 있는 방법이 있을거 같아 찾아보니
"MySQL에서는 INSERT ... ON DUPLICATE KEY UPDATE를 사용하여 레코드가 존재하면 업데이트하고, 존재하지 않으면 삽입하는 동작을 한 번의 쿼리로 수행할 수 있습니다. 그러나 먼저 이를 사용하려면 해당 테이블에 기본 키나 유니크 키 제약 조건이 있어야 합니다."
라고 챗 GPT가 알려줬다.
const query = `
INSERT INTO DBNAME.${table_name} (A, B)
VALUES ('${a}', '${b}')
ON DUPLICATE KEY UPDATE B = '${_b}';
`;
그리고 DUPLICATE KEY의 경우 "중복키 제약 조건"에 위배되는 경우 업데이트를 하는 구문이기 때문에
PK를 잘 설정해 주어야 한다.
상황에 따라 다르겠지만 현재는 유니스왑 v3의 틱을 PK로 설정해 두고 틱별 데이터를 저장 하려고 했기 때문에 틱을 PK로 두었다.
const query = `
INSERT INTO DBNAME.${table_name} (A, B)
VALUES ('${a}', '${b}')
ON DUPLICATE KEY UPDATE B = B + '${_b}';
`;
또한 만약 B가 토큰의 개수라고 치면 토큰 개수의 합산을 위해서는 다음과 같이 업데이트 구문을 바꿔 줄 수 도 있다.
그럼 업데이트가 2개 되는 구문은?
const query = `
INSERT INTO DBNAME.${table_name} (A, B)
VALUES ('${a}', '${b}')
ON DUPLICATE KEY UPDATE
A = A + '${_a}',
B = B + '${_b}'
`;
이렇게 2개를 , 로 각각 지정해서 업데이트 해주면 된다.
물론 간현한 만큼 위와 같은 쿼리가 문제점도 있는데 바로 SQL injection 공격 에 취약하다는 것이다.
근데 해당 쿼리는 일단 블록체인 이벤트 데이터를 그대로 넣어주는 것이기도 하고 외부에서 호출하는 것이 아닌 내부에서 CronJob으로 사용하는 구문이고 시퀄라이즈도 사용중이기 때문에 SQL injection에 대한 문제가 없어 그대로 사용하였다.
그리고 해당 경우 시퀄라이즈에서 사용할때는
.query(query)
다음과 같이 queryTypes를 안주면 된다. 또한 여기에 대한 응답값은 [0,2000] 이런식으로 나오는데 앞의 값은 0이 나오는 것이고 뒤의 값은 영향을 받은 행의 수라고 한다.
const [results, metadata] = await sequelize.query("UPDATE users SET y = 42 WHERE x = 12");
// Results will be an empty array and metadata will contain the number of affected rows.
위 코드의 출저인 시퀄라이즈 공식 문서링크는 아래와 같다.
https://sequelize.org/docs/v6/core-concepts/raw-queries/
'개발 > database' 카테고리의 다른 글
DB에서 인덱싱하는 법과 Sequalize에서 테이블 정의 시 index 넣는 방법 (0) | 2023.09.15 |
---|---|
Sequalize와 raw query를 통하여 updated at, created at 만들기 (0) | 2023.08.25 |
MySQL) 쿼리 실행 순서 및 테이블 합치기 (0) | 2023.02.14 |
스마트컨트렉트, 백엔드 , DB사이의 작업 처리에 대하여 (MySQL 다중 테이블 쿼리 + 백엔드 처리) (0) | 2023.02.13 |
Mysql에서 Json Extract & group by & CAST로 스마트 컨트렉트 이벤트 처리하기 (0) | 2023.02.08 |