도커 debian:trixie 컨테이너에서 작성된 게시글입니다.
헤더
#include <libpq-fe.h>
DB접속
PGconn* conn = PQconnectdb("host=postgres user=postgres port=5432 dbname=postgres password=password");
host에 적힌 postgres는 docker compose 파일에서 설정한 postgresql 서비스 이름이다.
DB연결 해제
커넥션을 종료하고, 메모리를 해제함. DB 연결이 실패하더라도 메모리는 할당되기 때문에 써줘야한다.
void PQfinish(PGconn *conn);
sql문 요청
PGresult* rst = PQexec(conn, "insert into auth.users (name, emailaddress, hashed_pw) \
values ('dodontak', 'abc@naver.com', 'abc12345');");

잘 만들어진다. 하지만 이 함수는 쿼리문을 만들 때
string sql = "INSERT INTO auth.users VALUES ('" + name + "', '" + email + "');";
이런식으로 작성하면 사용자가 name에 "'; DROP TABLE users; --" 같은걸 넣어서 데이터를 날리는 SQL Injection공격의 위험이 있다. 그래서 이 함수 대신 PQexecParams를 사용하는것을 권장한다고 한다.
PGresult *PQexecParams(PGconn *conn,
const char *command,
int nParams,
const Oid *paramTypes,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
// 1. 쿼리문에는 $1, $2 처럼 번호만 매김
const char* sql = "INSERT INTO auth.users (name, emailaddress) VALUES ($1, $2);";
// 2. 값만 따로 배열로 준비
const char* paramValues[2] = {"dodontak", "abc@naver.com"};
// 3. 한꺼번에 전달 (libpq가 알아서 안전하게 처리함)
PQexecParams(conn, sql, 2, NULL, paramValues, NULL, NULL, 0);
| 인자명 | 역할 | 설명 |
| conn | 연결 객체 | PGconnectdb등으로 생성된 포인터 |
| command | SQL 명령어 | $1, $2같이 파라미터 번호를 사용한 쿼리문 |
| nParams | 파라미터 개수 | 뒤에 따라올 배열들의 길이 결정 |
| paramTypes[] | 데이터 타입 | NULL이나 0넣으면 DB가 알아서 타입 추론 |
| paramValues[] | 실제 데이터 값 | 문자열 배열 형태로 값 전달 |
| paramLengths[] | 데이터 길이 | 바이너리 전송 시에만 필요. 텍스트전송 시 무시됨 |
| paramFormats[] | 데이터 형식 | 0이면 텍스트(기본), 1이면 바이너리 |
| resultFormat | 결과 값 형식 | 0이면 텍스트(기본), 1이면 바이너리 포멧으로 받음 |
텍스트랑 바이너리가 있는데 보통 텍스트로 한다고 함.
데이터 타입은 타입번호를 넘거야한다. INT4 는 23번, INT8은 20번 TEXT는 25번 등등... 필수는 아니고 NULL이나 0을 넣으면 서버가 알아서 추측한다. 무슨 타입인지 모호할때는 직접 OID번호를 적어주는게 좋다.
Oid types[2] = {25, 0}; // 1번은 TEXT타입, 2번은 알아서 추론
const char* values[2] = {"5512555125", "abc@naver.com"};
PQexecParams(
conn,
"INSERT INTO auth.users (name, email) VALUES ($1, $2)",
2,
types, // 여기에 타입 번호 배열 전달
values,
NULL,
NULL,
0
);
PGresult
PQexecParams 함수는 PGresult를 리턴하는데, SELECT결과, INSERT/UPDATE 성공여부, 에러미시지, 영향받은 row수 와 같은 정보를 담고있는 메모리 덩어리다. 정확한 내용을 확인하기 위해서는 접근 함수를 사용해야 한다. 자주쓰일법한 접근함수들을 정리해봤다.
접근함수로 얻는 메모리는 모두 PGresult에 포함된 메모리이기 때문에 PQclear 함수로 메모리를 해제하면 사용할 수 없다.
PQresultStatus
쿼리 실행 결과를 알려주는 함수
ExecStatusType PQresultStatus(const PGresult *res);
/* ExecStatusTypes
PGRES_EMPTY_QUERY : 보낸 쿼리 문자열이 빈 값임 (클라이언트측 문제 확인)
PGRES_COMMAND_OK : INSERT, UPDATE, DELETE 성공. (데이터 반환x)
PGRES_TUPLES_OK : SELECT 성공 (결과 0건도 포함)
PGRES_COPY_OUT : 서버에서 데이터를 받는 COPY 시작.
PGRES_COPY_IN : 서버로 데이터를 보내는 COPY 시작.
PGRES_BAD_RESPONSE : 서버의 응답을 해석할 수 없음 (네트워크 문제 확인)
PGRES_NONFATAL_ERROR : 경고(Notice) 또는 알림 발생
PGRES_FATAL_ERROR : 치명적 오류로 쿼리 실행 실패 (쿼리문법 오류, 권한문제 확인)
PGRES_COPY_BOTH : 양방향 데이터 전송 (주로 스트리밍 복제용, 일반 앱에선 보기 힘듦)
PGRES_SINGLE_TUPLE : 단일 행 모드에서 한 개의 행 반환 (PQsetSingleRowMode 사용시)
PGRES_TUPLES_CHUNK : 청크 모드에서 설정된 단위만큼 행 반환 (PQsetChunkedRowsMode 사용시)
PGRES_PIPELINE_SYNC : 파이프라인의 동기화 지점에 도달함
PGRES_PIPELINE_ABORTED : 파이프라인 실행 중 에러 발생으로 인해 이후 명령들이 중단됨
*/
PQclear
PGresult의 메모리할당을 해제해주는 함수.
void PQclear(PGresult *res);
PQresultErrorMessage
에러 메시지를 리턴하는 함수. 에러가 없으면 빈 문자열을 리턴한다.
char *PQresultErrorMessage(const PGresult *res);
데이터 가져오는 함수들
int PQntuples(const PGresult *res);
int PQnfields(const PGresult *res);
char *PQfname(const PGresult *res,
int column_number);
int PQfnumber(const PGresult *res,
const char *column_name);
char *PQgetvalue(const PGresult *res,
int row_number,
int column_number);
int PQgetisnull(const PGresult *res,
int row_number,
int column_number);
Oid PQftype(const PGresult *res,
int column_number);
- PQntuples : result의 row 갯수 리턴하는 함수
- PQnfields : result의 col 갯수 리턴하는 함수
- PQfname : n번째 col의 이름이 뭔지 리턴하는 함수
- PQfnumber : col_name이 몇번째 컬럼인지 리턴하는 함수. 없으면 -1 반환함
- PQgetvalue : 특정 row, col의 데이터를 리턴하는 함수. row col은 0부터 시작. 데이터는 PQclear와 함께 소멸되니 주의. 해당 필드가 NULL이라면 빈 문자열을 리턴한다.
- PQgetisnull : 특정 row, col이 NULL인지 확인하는 함수. getvalue로 빈문자열이 나왔는데 진짜 빈 문자열인지 NULL인지 이 함수를 사용해서 확인할 수 있다.
- PQftype : n번째 col의 타입이 뭔지 리턴하는 함수. (TEXT = 25, int4 = 23 등)
이외의 함수들은 아래 문서를 참조하자.
32.3. Command Execution Functions
32.3. Command Execution Functions # 32.3.1. Main Functions 32.3.2. Retrieving Query Result Information 32.3.3. Retrieving Other Result Information 32.3.4. Escaping Strings …
www.postgresql.org
'공부 > DB' 카테고리의 다른 글
| hiredis with.C/C++ (0) | 2026.03.09 |
|---|---|
| Redis 기초 (0) | 2026.03.08 |
| DBCP (DB connection pool) (0) | 2026.02.19 |
| DB Partitioning, Sharding, Replication (0) | 2026.02.19 |
| postgreSQL EXPLAIN ANALYZE (0) | 2026.02.18 |