
Pro*C中使用Unicode字符
What is Pro*C
Pro*C语言是Oracle开发的一种基于C语言并可以内嵌SQL的编程语言. 它通过Pro*C预编译器将Pro*C源码文件(后缀是.cp)转译成C源码文件, 后者可通过C编译器(gcc)编译为可执行程序.
Environment setup
1. header file and library
编写Pro*c所需要的头文件和C库均包含在oracle数据库的instantclient中. 请准备如下Makefile
INCLUDE=-I${ORACLE_HOME}/sdk/include/ -I${ORACLE_HOME}/precomp/public
LIBS=-L${ORACLE_HOME}/lib/ -L${ORACLE_HOME}/precomp/lib
main.c:main.pc
proc $^ oname=$@
main:main.c
gcc -ggdb -o main main.c ${INCLUDE} ${LIBS} -lclntsh
2. precompiler config
预编译器设置位于instantclient的$ORACLE_HOME/precomp/admin/pcscfg.cfg中, 可用如下设置
sys_include=($ORACLE_HOME/precomp/public,/usr/include)
sys_include=/usr/lib/gcc/x86_64-linux-gnu/13/include
sys_include=/usr/lib/gcc/x86_64-linux-gnu/14/include
sys_include=/usr/include/x86_64-linux-gnu/
sys_include=$ORACLE_HOME/sdk/include
ltype=short
define=__x86_64__
code=ansi_c
Let’s coding
Pro*C长这样:
#include <assert.h>
#include <sqlca.h>
#include <sqlcpr.h>
#include <sqlda.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// runtime error checking, i steal this code from demo
void sql_error(char *msg) {
char err_msg[512];
size_t buf_len, msg_len;
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf("\n%s\n", msg);
buf_len = sizeof(err_msg);
sqlglm(err_msg, &buf_len, &msg_len);
printf("%.*s\n", (int)msg_len, err_msg);
EXEC SQL ROLLBACK RELEASE;
exit(EXIT_FAILURE);
}
int main() {
assert(setenv("NLS_NCHAR", "AL32UTF8", 0) ==
0); // set this env var when working with unicode
char *ezconn = "SYS/[email protected]:21521/PDB";
EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--");
// if you work with unicode, declare variable like thie.
char character set nchar_cs str[64] = {0};
char tmp[64] = "こんにちは";
memcpy(str, tmp, 64);
EXEC SQL CONNECT : ezconn in sysdba mode;
EXEC SQL drop table if exists test; // 23c supports this syntax
EXEC SQL create table test(txt varchar2(128));
EXEC SQL insert into test values( : str);
EXEC SQL select txt into : str from test;
EXEC SQL COMMIT WORK RELEASE;
printf("%s\n", str);
}
- sql_error函数可以用来捕获oracle数据库返回的报错
- 在Pro*C中使用Unicode需要设置
NLS_NCHAR环境变量来设置字符集 - 声明指定字符集的字符串需要
char character set nchar_cs *var来声明var - 内嵌SQL中使用C变量像是在用绑定变量
Result
karl@karl:~/Projects/proc_unicode$ make main
proc main.pc oname=main.c
Pro*C/C++: Release 23.26.1.0.0 - Production on Wed Sep 16 20:06:11 2026
Version 23.26.1.0.0
Copyright (c) 1982, 2026, Oracle and/or its affiliates. All rights reserved.
System default option values taken from: /opt/oracle/product/23.26.1/client_1/precomp/admin/pcscfg.cfg
gcc -ggdb -o main main.c -I/opt/oracle/product/23.26.1/client_1/sdk/include/ -I/opt/oracle/product/23.26.1/client_1/precomp/public -L/opt/oracle/product/23.26.1/client_1/lib/ -L/opt/oracle/product/23.26.1/client_1/precomp/lib -lclntsh
karl@karl:~/Projects/proc_unicode$ ./main
こんにちは