返回首页

gbase数据、南大通用产品文档:GBase8s使用简单大对象编程

更新日期:2024年09月11日

GBase 8s ESQL/C 支持 SQL 简单大对象和使用 loc_t 数据类型的数据类型 TEXT
和 BYTE 。

提示: 不能在 INSERT 或 UPDATE 语句中使用文字值将简单大对象放入 TEXT
或 BYTE 列。要将值插入到一个简单大对象中,可以使用来自 GBase 8s ESQL/C 客户端
应用程序的 DB-Access 的 LOAD 语句或 loc_t主机变量。

由于简单大对象的潜在的巨大大小,则 GBase 8s ESQL/C 程序不会直接在 loc_t 主
机变量中存储数据。相反,loc_t 结构是定位程序结构。它不包含实际数据,它包含简单大
对象的大小和位置信息。您选择是否将数据存储在内存中、操作系统文件中或用户定义的
位置。

要在 GBase 8s ESQL/C 程序中使用简单大对象,请采取以下操作:
声明具有 loc_t 数据类型的主机变量
访问 loc_t 定位器结构的字段
为简单大对象声明主机变量
使用 loc_t 数据类型为 TEXT 或 BYTE 类型的数据库值声明主机变量。
为数据类型
loc_t 的简单大对象列声明一个主机变量,如下所示:
EXEC SQL include locator;


EXEC SQL BEGIN DECLARE SECTION;
loc_t text_lob;
loc_t byte_lob;
EXEC SQL END DECLARE SECTION;

具有 TEXT 数据类型的定位器变量具有定位器结的 loc_type 字段设置为
SQLTEXT。对于 BYTE 变量,loc_type 是 SQLBYTE。

提示:
sqltypes.h 头文件定义 SQLTEXT 和 SQLBYTE。
因此,
请确保在使用这些常

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 135 -

量之前包含了 sqltypes.h 。

从 GBase 8s ESQL/C 程序中,可以选择并将简单大对象数据插入到 loc_t 主变量中。
您也可以在简单大对象列名称上仅选择具有下标的简单大对象变量的部分。这些下标可以
编码到语句中,如下所示:
EXEC SQL declare catcurs cursor for
select catalog_num, cat_descr[1,10]
from catalog
where manu_code = 'HSK';
EXEC SQL open catcurs;
while (1)
{
EXEC SQL fetch catcurs into :cat_num, :cat_descr;



}

下标也可以作为输入参数传递,如以下代码片段所示:
EXEC SQL prepare slct_id from
'select catalog_num, cat_descr[?,?] from catalog \
where catalog_num = ?'
EXEC SQL execute slct_id into :cat_num, :cat_descr
using :n, :x, :cat_num;
访问定位器结构
在 GBase 8s ESQL/C 程序中,使用定位器结构访问简单大对象值。

当它们存储在数据库中或从数据库中检索时,
定位器结构是 TEXT 和 BYTE 列的主
机变量。此结构描述了以下两个数据库操作的简单大对象的位置:
当程序向数据库插入简单对象时,定位器结构标识要插入的简单大对象的源。
建议在使用数据结构之前进行初始化,如下所示:
byfill(&blob1, sizeof(loc_t), 0);
where blob1 is declared as --

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 136 -

EXEC SQL BEGIN DECLARE SECTION;
loc_t blob1;
EXEC SQL END DECLARE SECTION;

这样可以确保数据结构的所有变量都初始化,并避免不一致。
当程序从数据库中选择简单大对象时,定位器结构标识简单大对象的目的地。
locator.h 头文件定义名为 loc_t 的定位器结构。下图显示了来自 locator.h 文件中
loc_t 定位器结构的声明。

图 1. locator.h 头文件中 loc_t 的声明

typedef struct tag_loc_t
{
int2 loc_loctype; /* USER: type of locator - see below */
union /* variant on 'loc'
*/
{
struct /* case LOCMEMORY
*/
{
int4 lc_bufsize; /* USER: buffer size */
char *lc_buffer; /* USER: memory buffer to use */
char *lc_currdata_p; /* INTERNAL: current memory buffer */
mint lc_mflags; /* USER/INTERNAL: memory flags
*/
/* (see below) */
} lc_mem;

struct /* cases L0CFNAME & LOCFILE
*/
{
char *lc_fname; /* USER: file name */
mint lc_mode; /* USER: perm. bits used if creating */
mint lc_fd; /* USER: os file descriptior */

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 137 -

int4 lc_position; /* INTERNAL: seek position */
} lc_file;
} lc_union;

int4 loc_indicator; /* USER/SYSTEM: indicator
*/
int4 loc_type; /* SYSTEM: type of blob
*/
int4 loc_size; /* USER/SYSTEM: num bytes in blob or -1
*/
mint loc_status; /* SYSTEM: status return of locator ops
*/
char *loc_user_env; /* USER: for the user's PRIVATE use
*/
int4 loc_xfercount; /* INTERNAL/SYSTEM: Transfer count
*/
/* USER: open function */
mint (*loc_open)(struct tag_loc_t *loc, mint flag, mint bsize);
; /* USER: close function */
mint (*loc_close)(struct tag_loc_t *loc)
; /* USER: read function */
mint (*loc_read)(struct tag_loc_t *loc, char *buffer, mint buflen)
; /* USER: write function */
mint (*loc_write)(struct tag_loc_t *loc, char *buffer, mint buflen)
/* USER/INTERNAL: see flag definitions below */
mint loc_oflags;
} loc_t;

在图 1中,locator.h 文件中的以下示例说明了如何在定位器结构中使用字段。


USER
GBase 8s ESQL/C 程序设置此字段,GBase 8s ESQL/C 库检查此字段。
SYSTEM
GBase 8s ESQL/C 库设置此字段,GBase 8s ESQL/C 程序检查此字段。
INTERNAL

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 138 -

此字段是 GBase 8s ESQL/C 库的工作区,GBase 8s ESQL/C 程序不需要检查此
字段。

GBase 8s ESQL/C 不会在 GBase 8s ESQL/C 程序中自动包含 locator.h 头文件。您必
须在定义简单大对象变量的任何 GBase 8s ESQL/C 程序中包含 locator.h 头文件。
EXEC SQL include locator;
定位器结构的字段
定位器结构具有以下部分:
loc_loctype 字段标识简单大对象的位置。它还标识 lc_union 结构的可变类型。
lc_union 结构是 union (重叠的可变结构)结构。
使用的变量取决于 GBase 8s ESQL/C 可以在运行时找打简单大对象的位置。
所有类型的简单大对象变量都有几个字段。
列出所有简单大对象位置中常见的定位器结构中的字段。

表 1. 简单大对象位置中常见的定位器结构中的字段
字段
数据类型
描述
loc_indicator
4 字
节整数
loc_indicator 字段的值为 -1 时表示空简单大对象。
GBase 8s ESQL/C 程序可以将此字段设置为指示插入空值;
GBase 8s ESQL/C 库将其设置为 select 或 fetch。
为了在各种平台上保持一致的行为,
建议将指标值设置为
0 或 -1。如果指示符未设置,您可能会遇到不一致的行为。
设置时,指示字段中设置的值优先。

还可以使用 loc_indicator 字段来指示程序在内存中选
择的错误。如果要检索的简单大对象不适合提供的空间,则
loc_indicator 字段包含简单大对象的实际大小。

loc_size
4 字
节整数
包含简单大对象的大小(以字节为单位)。 该字段指示
GBase 8s ESQL/C 库读取或写入的简单大对象的数据量。
GBase 8s ESQL/C 程序在数据库中插入一个简单大对象时,

置 GBase 8s ESQL/C 库在选择或获取一个简单大对象后设置
了 loc_size。
loc_status
mint
指示最后一个定位器操作的状态。当定位器操作成功时,
GBase 8s ESQL/C 库将 loc_status 设置为零,
当发生错误时设
置为负数。 SQLCODE 变量还包含此状态值。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 139 -

字段
数据类型
描述
loc_type
4 字
节整数
指定变量的数据类型是 TEXT(SQLTEXT)还是 BYTE
(SQLBYTES)。sqltypes.h 头文件定义 SQLTEXT 和
SQLBYTES。
简单大对象数据的位置
在 GBase 8s ESQL/C 程序访问简单大对象列之前,它必须确定简单大对象的位置。

要指定简单大对象是位于内存或文件中,请指定定位器结构的 loc_loctype 字段的内
容。下表显示了简单大对象数据的可能位置。

表 2. 简单大对象数据的可能位置
loc_loctype 字段的值
简单大对象数据的位置
请参阅
LOCMEMORY
在内存中
在内存中找
到简单大对

LOCFILE
在打开的文件中
在打开文件
中定位简单
大对象
LOCFNAME
在已命名的文件中
在已命名的
文件中定位
简单大对象
LOCUSER
在用户定义的位置
用户定义的
简单大对象
位置

在声明定位器变量之后,在此声明的变量接收到简单大对象值之前,请设置
loc_loctype。

locator.h 头文件定义 LOCMEMORY 、LOCFILE 、LOCFNAME 和 LOCUSER 位
置常量。在您的 GBase 8s ESQL/C 程序中,当将值分配给 loc_loctype 时,请使用这些常
量名称而不是他们的常量值。

在客户端服务器环境中,
GBase 8s ESQL/C 在客户端计算机
(运行应用程序的计算机)
上找到简单大对象。

本章介绍了GBase 8c 内存优化表(Memory-Optimized Table,MOT)的特性及价值、关
键技术、应用场景、性能基准和竞争优势。

本示例实现了如下功能:

NationalCharacterSimple.simpleGetNClob 获取Nclob 类型内容。

NationalCharacterSimple.simpleSetNClob()通过
PreparedStatement.SetNClob 实现NClob 的存入数据库。

nationalCharacterSimple.simpleUpdateNClob()通过
PreparedStatement.UpdateNClob 实现Nclob 字段的更新。
更多关于NATIONAL CHARACTER 操作示例请参照工程。
示例如下:
package com.gbase.jdbc.simple;

import java.io.Reader;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class NationalCharacterSimple {

private static final String URL =
"jdbc:gbase://192.168.111.95:5258/test?user=sysdba&password=";

/**
* Runs all test cases in this test suite
*
* @param args
*/
public static void main(String[] args) {
NationalCharacterSimple nationalCharacterSimple = new

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1090
NationalCharacterSimple();
try {
nationalCharacterSimple.simpleGetNClob();
nationalCharacterSimple.simpleSetNClob();
nationalCharacterSimple.simpleUpdateNClob();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

/**
* Simple for ResultSet.getNClob()
*
* @throws Exception
*/
public void simpleGetNClob() throws Exception {
Connection conn = null;
Statement stm = null;
ResultSet rs = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(URL);
stm = conn.createStatement();
createTable("simpleGetNClob", "(c1 NATIONAL CHARACTER(10),
c2 NATIONAL CHARACTER(10))", stm);
stm.executeUpdate("INSERT INTO simpleGetNClob (c1, c2) VALUES
(_utf8 'aaa', _utf8 'bbb')");
rs = stm.executeQuery("SELECT c1, c2 FROM simpleGetNClob");
rs.next();
char[] c1 = new char[3];

rs.getNClob(1).getCharacterStream().read(c1);
System.out.println(new String(c1));
char[] c2 = new char[3];

rs.getNClob("c2").getCharacterStream().read(c2);
System.out.println(new String(c2));

}catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1091
e.printStackTrace();
} finally {
try {
rs.close();
} catch (NullPointerException e) {
} catch (Exception e) {
rs = null;
}


try {
stm.close();
} catch (NullPointerException e) {
} catch (Exception e) {
stm = null;
}
try {
conn.close();
} catch (NullPointerException e) {
} catch (Exception e) {
conn = null;
}
}
}
/**
* Simple for PreparedStatement.setNClob()
*
* @throws Exception
*/
public void simpleSetNClob() throws Exception {

Connection conn = null;
Statement stm = null;
PreparedStatement pstm = null;
ResultSet rs = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn =
DriverManager.getConnection(URL+"&useServerPrepStmts=false&useUnicode=true&char
acterEncoding=utf-8");
stm = conn.createStatement();

createTable("simpleSetNClob", "(c1 NATIONAL CHARACTER(10),
c2 NATIONAL CHARACTER(10), " +
"c3 NATIONAL CHARACTER(10))", stm);
pstm = conn.prepareStatement("INSERT INTO simpleSetNClob (c1, c2,

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1092
c3) VALUES (?, ?, ?)");
pstm.setNClob(1, (NClob)null);
NClob nclob2 = conn.createNClob();
nclob2.setString(1, "aaa");
pstm.setNClob(2, nclob2); // for setNClob(int, NClob)

Reader reader3 = new StringReader("\'aaa\'");
reader3 = new StringReader("\'aaa\'");
pstm.setNClob(3, reader3, 5); // for setNClob(int, Reader,
long)
pstm.execute();
rs = stm.executeQuery("SELECT c1, c2, c3 FROM simpleSetNClob");
rs.next();

//null
System.out.println(rs.getString(1));

//"aaa"
System.out.println(rs.getString(2));

//"\'aaa\'"
System.out.println(rs.getString(3));
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
rs.close();
} catch (NullPointerException e) {
} catch (Exception e) {
rs = null;
}


try {
stm.close();
} catch (NullPointerException e) {
} catch (Exception e) {
stm = null;
}
try {
pstm.close();
} catch (NullPointerException e) {

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1093
} catch (Exception e) {
pstm = null;
}
try {
conn.close();
} catch (NullPointerException e) {
} catch (Exception e) {
conn = null;
}
}
}
/**
* Simple for ResultSet.updateNClob()
*
* @throws Exception
*/
public void simpleUpdateNClob() throws Exception {

Connection conn = null;
Statement stm = null;
PreparedStatement pstm = null;
ResultSet rs = null;
ResultSet rs2 = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn =
DriverManager.getConnection(URL+"&useUnicode=true&characterEncoding=utf-8");
stm = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);

createTable("simpleUpdateNChlob",


"(c1 CHAR(10) PRIMARY KEY, c2
NATIONAL CHARACTER(10)) default character set utf8", stm);
pstm = conn.prepareStatement("INSERT INTO simpleUpdateNChlob
(c1, c2) VALUES (?, ?)");
pstm.setString(1, "1");
NClob nClob1 = conn.createNClob();
nClob1.setString(1, "aaa");
pstm.setNClob(2, nClob1);
pstm.execute();
rs = stm.executeQuery("SELECT c1, c2 FROM
simpleUpdateNChlob");
rs.next();
NClob nClob2 = conn.createNClob();

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1094
nClob2.setString(1, "bbb");
rs.updateNClob("c2", nClob2);
rs.updateRow();(移动到这行然后修改改行数据)
rs.moveToInsertRow();
rs.updateString("c1", "2");
NClob nClob3 = conn.createNClob();
nClob3.setString(1, "ccc");
rs.updateNClob("c2", nClob3);
rs.insertRow();(移动到插入点然后插入新数据)
rs2 = stm.executeQuery("SELECT c1, c2 FROM
simpleUpdateNChlob");
rs2.next();

//"1"
System.out.println(rs2.getString("c1"));

//"bbb"

System.out.println(rs2.getNString("c2"));
rs2.next();

//"2"
System.out.println(rs2.getString("c1"));

//"ccc"

System.out.println(rs2.getNString("c2"));
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
rs.close();
} catch (NullPointerException e) {
} catch (Exception e) {
rs = null;
}
try {
rs2.close();
} catch (NullPointerException e) {
} catch (Exception e) {

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1095
rs2 = null;
}
try {
stm.close();
} catch (NullPointerException e) {
} catch (Exception e) {
stm = null;
}
try {
pstm.close();
} catch (NullPointerException e) {
} catch (Exception e) {
pstm = null;
}
try {
conn.close();
} catch (NullPointerException e) {
} catch (Exception e) {
conn = null;
}
}
}
private void createTable(String objectName,



String columnsAndOtherStuff, Statement stmt) throws SQLException {
createSchemaObject("TABLE", objectName, columnsAndOtherStuff, stmt);
}
private void createSchemaObject(String objectType, String objectName,



String columnsAndOtherStuff, Statement stmt) throws SQLException {
dropSchemaObject(objectType, objectName, stmt);

StringBuffer createSql = new StringBuffer(objectName.length() +
objectType.length() + columnsAndOtherStuff.length() + 10);
createSql.append("CREATE ");
createSql.append(objectType);
createSql.append(" ");
createSql.append(objectName);
createSql.append(" ");
createSql.append(columnsAndOtherStuff);

try {
stmt.executeUpdate(createSql.toString());
} catch (SQLException sqlEx) {
throw sqlEx;
}

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1096
}
private void dropSchemaObject(String objectType, String objectName, Statement
stmt)

throws SQLException {
stmt.executeUpdate("DROP " + objectType + " IF EXISTS "


+ objectName);
}
}