콘텐츠로 이동

SQL과 값 바인딩

Unibase 소스 안에는 SQL 문장 표현식을 작성할 수 있습니다. SQL을 문자열 연결로 만들기보다 소스의 값을 문장에 전달하는 구조를 살펴봅니다. 두 소스는 실행할 때 테이블을 만들고 실제 Unibase DB에 값을 저장·조회합니다. 빌드·실행을 누르면 저장 뒤 읽은 값과 빈 조회 결과를 확인할 수 있습니다. 예제마다 독립된 임시 DB를 사용하므로 이전 실행의 데이터가 다음 결과에 섞이지 않습니다.

다른 언어의 탭에서는 값 바인딩·행 조회·빈 결과 처리를 비교할 수 있도록 SQLite 메모리 DB를 사용합니다. Java는 SQLite JDBC 드라이버, C#은 Microsoft.Data.Sqlite, Go는 modernc.org/sqlite 의존성이 필요합니다. Python은 표준 sqlite3, TypeScript는 Node.js의 node:sqlite를 사용합니다. Unibase의 SQL 문장 표현식은 원본 탭에서 그대로 확인할 수 있습니다.

_name은 소스의 문자열 변수이며 VALUES(_name)에서 사용합니다. _sql의 오른쪽은 큰따옴표로 감싼 문자열이 아니라 SQL 문장 표현식입니다.

class SqlInsertBinding {
    static void main() {
        CREATE TABLE example_users (id INT, name TEXT);
        var _name = "Kim";
        var _sql = INSERT INTO example_users (id, name) VALUES(1, _name);
        var result = _sql.execute();
        ResultSet rows = SELECT name FROM example_users WHERE id = 1;
        print(rows.rowCount());
        print(rows.getString(0, "name"));
    }
}

다른 언어의 탭은 직접 작성한 대응 코드이며 컴파일러의 자동 생성 결과가 아닙니다. 언어마다 API와 실행 환경이 다릅니다. 이 페이지의 빌드·실행은 Unibase 탭에서 사용할 수 있습니다.

서버 실행을 준비 중입니다.
출력 비교 기준
1
Kim
Unibase 소스 내려받기

검증 상태: 문법 검사 통과 · 실행 출력 일치 (2026-10-06)

읽기 기준 결과와 실제 실행 출력 비교

코드를 읽어 정한 비교 기준입니다. 실행 성공 결과로 대신 표시하지 않습니다.

1
Kim

실제 네이티브 실행: 빌드 passed, 실행 passed, 종료 코드 0

1
Kim
현재 실행 확인 범위

CREATE TABLE은 id·name 열을 준비합니다. _sql은 INSERT 문장을 보관하고 execute()에서 수행합니다. 그 뒤 SELECT로 다시 읽은 행 수 1과 저장 값 Kim을 출력합니다. 변수 이름만으로 모든 SQL 바인딩 방식이 같다고 일반화하지 않습니다.

_id를 조건에 사용하고 결과를 ResultSet에 받는 형태입니다. getString(0, "name")은 첫 행의 name 값을 읽는 호출입니다.

class SqlSelectBinding {
    static void main() {
        CREATE TABLE example_users (id INT, name TEXT);
        INSERT INTO example_users (id, name) VALUES(1, 'Kim');
        int _id = 1;
        ResultSet rows = SELECT name FROM example_users WHERE id = _id;
        string name = rows.getString(0, "name");
        print(name);
        ResultSet empty = SELECT name FROM example_users WHERE id = 99;
        print(empty.rowCount());
        print(empty.isEmpty());
    }
}

다른 언어의 탭은 직접 작성한 대응 코드이며 컴파일러의 자동 생성 결과가 아닙니다. 언어마다 API와 실행 환경이 다릅니다. 이 페이지의 빌드·실행은 Unibase 탭에서 사용할 수 있습니다.

서버 실행을 준비 중입니다.
출력 비교 기준
Kim
0
true
Unibase 소스 내려받기

검증 상태: 문법 검사 통과 · 실행 출력 일치 (2026-10-06)

읽기 기준 결과와 실제 실행 출력 비교

코드를 읽어 정한 비교 기준입니다. 실행 성공 결과로 대신 표시하지 않습니다.

Kim
0
true

실제 네이티브 실행: 빌드 passed, 실행 passed, 종료 코드 0

Kim
0
true
현재 실행 확인 범위

소스의 첫 두 문장은 테이블과 초기 행을 준비합니다. _id = 1인 조회는 Kim을 얻고, id = 99인 조회는 rowCount()가 0이며 isEmpty()가 true입니다. 빈 결과에서 첫 행을 읽지 않는 흐름이 중요합니다. 운영 DB의 연결·트랜잭션·마이그레이션 절차는 별도 계약으로 다룹니다.

SQL 문장을 표현하는 값, 그 문장을 실행하는 호출, 실행 뒤 얻는 결과는 서로 다른 단계입니다. 문장 소스가 검사됐다고 데이터베이스 연결과 저장까지 확인된 것은 아닙니다.

단계 본문의 소스에서 찾을 것
값 준비 _name, _id의 타입과 값
문장 표현 INSERT의 VALUES, SELECT의 WHERE
수행 또는 조회 execute() 또는 ResultSet을 받는 표현식
결과 사용 조회 행과 열 이름

SQL에 값을 전달하는 것과 테이블·열 이름을 문자열로 조립하는 것은 구분해야 합니다. 사용자가 입력한 SQL 조각을 임의 실행하는 기능은 이 문서의 서버 예제에 없습니다.

현재 ResultSet에는 다음 메서드가 선언되어 있습니다.

선언 용도
int rowCount() 결과 행 수 조회
bool isEmpty() 비어 있는 결과 조회
string getString(int row, string column) 행 번호와 열 이름으로 문자열 조회

getString(0, "name")을 사용하려면 첫 행과 해당 열이 존재해야 합니다. 0은 행 번호이고 "name"은 열 이름이므로 서로 바꾸어 전달할 수 없습니다. 현재 native 경로는 없는 행·열에 런타임 오류를 보고합니다. SQL NULL의 문자열 변환과 타겟별 차이는 별도 검증 범위입니다.

본문은 검증된 native 경로의 직접 SQL 문장 표현식을 사용합니다. _name 같은 소스 변수는 문장의 값 위치에 전달되며 문자열 안의 작은따옴표는 SQL 문자열 규칙에 맞춰 처리합니다. 언어 명세의 sql { ... }와 :name 표현, 외부 DB와의 연동을 같은 지원 범위로 일반화하지 않습니다.

SQL 구문 오류·없는 테이블·없는 열·잘못된 행 번호는 다른 실패 원인입니다. 먼저 빌드와 실행 중 어느 단계가 실패했는지 읽고 진단을 확인하세요. 프로세스 종료 코드만 확인하지 말고 실제 행 수와 값을 비교합니다. 오류와 예외에서 단계별 실패를 구분하는 방법을 읽을 수 있습니다.