ODBC Users` Manual

Add to My manuals
280 Pages

advertisement

ODBC Users` Manual | Manualzz

echo "ERROR select: $msg\n"; exit;

}

$rownumber = 0; while (odbc_fetch_row($Result1))

{

$data1 = odbc_result($Result1, 1);

$data2 = odbc_result($Result1, 2);

$data3 = odbc_result($Result1, 3);

$len2 = strlen($data2);

$len3 = strlen($data3); print "\n==========================================\n"; print "Row $rownumber....\n";

$rownumber++; print "data1 = ".$data1."\n"; print "-------\n"; print "data2 = \n";

// print $data2; // Output is omitted because this is binary data.

print "\n"; print "dataLen2 = [$len2]\n"; print "-------\n"; print "data3 = \n"; print $data3; print "\n"; print "dataLen3 = [$len3]\n";

} odbc_commit($Connection);

@odbc_close($Connection);

?>

Other Changes

Other Changes

This section describes changes except data types.

SQLCloseCursor

You can call functions in the following order because there isn’t ODBC state machine in Altibase4 CLI library.

SQLHSTMT stmt;

SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);

SQLPrepare(stmt, (SQLCHAR *)”SELECT I1 FROM T1”, SQL_NTS);

SQLExecute(stmt);

SQLFetch(stmt);

SQLExecute(stmt);

However, if you execute codes above with ODBC-CLI in Altibase5, function sequence error occurs in

SQLExecute(stmt). Because stmt performing SQLExecute() first indicates to generate result set.

Therefore, ODBC cursor becomes open and state of stmt indicates S5. (Refer to MSDN ODBC specification.). However, error occurs in this state cause of no performing SQLExecute().

If you want to perform SQLExecute() again, call SQLCloseCursor() clearly as follows and then make stmt have S1 or S3 state.

255 Upgrade

Other Changes

SQLExecute(stmt);

SQLFetch(stmt);

SQLCloseCursor(stmt);

SQLExecute(stmt);

SQLBindParameter - ColumnSize Argument

ColumnSize of SQLBindParameter() as the 6th parameter in Altibase 5 is different from that of previous one.

If you insert 0 into this argument for previous version, no problem.

However, if you insert maximum length of data transmitted to server in Altibase 5, its performance has problem because it checks their information whenever executed.

SQLBindParameter – StrLen_or_IndPtr Argument

CLI library in Altibase 4 references data only if they, which StrLen_or_IndPtr argument indicates, have variable length.

However, Altibase 5 references the values in the memory StrLen_or_IndPtr argument indicates whenever performing SQLExecute() or SQLExecDirect() because Altibase 5 can implement SQLPut-

Data() and SQLParamData().

Therefore, you need special care in perfectly initializing memory the pointer indicates if sending

StrLen_or_Ind as the last argument of SQLBindParameter() to not Null pointer but valid pointer variables.

If SQL_DATA_AT_EXEC is -2 as constant number or SQL_LEN_DATA_AT_EXEC() is less than -100 without initializing memory completely, CLI library judges user intends to send the argument with

SQLPutData(). And CLI library returns SQL_NEED_DATA when you call SQLExecute().

If SQLExecDirect() returns the unintended value(SQL_NEED_DATA) cause of no initialized value above, this influences on functions called next. So you need special care that function sequence errors in all functions called next cause to return SQL_ERROR.

SQLPutData(), SQLParamData()

ODBC-CLI in Altibase 5 supports SQLPutData() and SQLParamData() provided not in previous version. Refer to MSDN for details about each function.

The following is the example program with using functions and StrLen_or_IndPtr mentioned above.

Table Schema :

CREATE TABLE T2_CHAR (I1 INTEGER, I2 CHAR(50)); void putdata_test(void)

{

SQLRETURN sRetCode;

SQLHANDLE sStmt;

SQLINTEGER i1;

SQLLEN i1ind;

ODBC User’s Manual 256

Other Changes

SQLCHAR *i2[10] =

{

(unsigned char *)"0000000000000.",

(unsigned char *)"1111111111111. test has been done.",

(unsigned char *)"2222222222222. Abra ca dabra",

(unsigned char *)"3333333333333. Short accounts make long friends.",

(unsigned char *)"4444444444444. Whar the hell are you doing man!",

(unsigned char *)"5555555555555. Oops! I missed this row. What an idiot!",

(unsigned char *)"6666666666666. SQLPutData test is well under way.",

(unsigned char *)"7777777777777. The length of this line is well over 50

characters.",

(unsigned char *)"8888888888888. Hehehe",

(unsigned char *)"9999999999999. Can you see this?",

};

SQLLEN i2ind;

SQLINTEGER i;

SQLINTEGER sMarker = 0; i1ind = SQL_DATA_AT_EXEC; i2ind = SQL_DATA_AT_EXEC; sRetCode = SQLAllocHandle(SQL_HANDLE_STMT, gHdbc, &sStmt); check_error(SQL_HANDLE_DBC, gHdbc, "STMT handle allocation", sRetCode); sRetCode = SQLBindParameter(sStmt, 1, SQL_PARAM_INPUT,

SQL_C_SLONG, SQL_INTEGER,

0, 0, (SQLPOINTER *)1, 0, &i1ind); sRetCode = SQLBindParameter(sStmt, 2, SQL_PARAM_INPUT,

SQL_C_CHAR, SQL_CHAR,

60, 0, (SQLPOINTER *)2, 0, &i2ind); sRetCode = SQLPrepare(sStmt,

(SQLCHAR *)"insert into t2_char values (?, ?)", SQL_NTS); for(i = 0; i < 10; i++)

{ i1 = i + 1000; printf("\n"); printf(">>>>>>>> row %d : inserting %d, \"%s\"\n", i, i1, i2[i]); sRetCode = SQLExecute(sStmt); if(sRetCode == SQL_NEED_DATA)

{ sRetCode = SQLParamData(sStmt, (void **)&sMarker); while(sRetCode == SQL_NEED_DATA)

{ printf("SQLParamData gave : %d\n", sMarker); if(sMarker == 1)

{ sRetCode = SQLPutData(sStmt, &i1, 0);

} else if(sMarker == 2)

{ int unitsize = 20; int size; int pos; int len;

257 Upgrade

Other Changes len = strlen((char *)(i2[i])); for(pos = 0; pos < len;)

{ size = len - pos; if(unitsize < size)

{ size = unitsize;

} sRetCode = SQLPutData(sStmt, i2[i] + pos, size);| pos += size;

}

} else

{ printf("bbbbbbbbbbbbbbbbbbbbbbbbbbbbb!!! unknown marker value\n"); exit(1);

} sRetCode = SQLParamData(sStmt, (void **)&sMarker);

}

}

} sRetCode = SQLFreeHandle(SQL_HANDLE_STMT, sStmt); check_error(SQL_HANDLE_DBC, gHdbc, "STMT free", sRetCode);

}

Limitation on ALTER SESSION statements

Altibase 4 specifies AUTOCOMMIT MODE and DEFAULT_DATE_FORMAT as session properties as follows.

SQLExecDirect(stmt,

“ALTER SESSION SET AUTOCOMMIT=FALSE”,

SQL_NTS);

SQLExecDirect(stmt,

“ALTER SESSION SET DEFAULT_DATE_FORMAT='YYYY/MM/DD'",

SQL_NTS);

2 session properties above must have information on ODBC-CLI because they definitely affect conversion of ODBC-CLI and operation of functions related to transactions.

However, ODBC-CLI can’t know property changes if transmitting SQL syntaxes to server directly with using SQLExecDirect().

ODBC-CLI can get information from server to know the values of property, but this causes to have worse performance.

In Altibase 5 the property is modified with SQLSetConnectAttr() to solve this problem. Altibase 5 always makes the property in ODBC-CLI same as that in server.

Altibase executes as follows when using ODBC-CLI.

SQL_ATTR_AUTOCOMMIT,

(SQLPOINTER)SQL_AUTOCOMMIT_OFF,

0);

SQLSetConnectAttr(conn,

ALTIBASE_DATE_FORMAT,

ODBC User’s Manual 258

Other Changes

(SQLPOINTER)"YYYY/MM/DD",

SQL_NTS);

SQLRowCount(), SQLMoreResults() functions

There are 2 results of ODBC.

Number of affected rows

• Result set

ODBC-CLI considers multiple results in Altibase 5. In other words, you can get them by one execution. Therefore, returned results of SQLRoewCount() are different from those of Altibase 4 when you use array binding.

SQLRowCount() : gets affected row count in “current” result.

SQLMoreResults() : moves to “next” result and returns SQL_NO_DATA if current result is last.

Example

CREATE TABLE T1 (I1 INTEGER);

INSERT INTO T1 VALUES(1);

INSERT INTO T1 VALUES(2); ........ repeat 1000 times

2

3

.

.

SELECT * FROM T1;

T1

-----

1

.

1000

-----

SQLINTEGER p1[3];

SQLINTEGER p2[3];

SQLLEN rowcount = 0L;

SQLLEN totalRowcount = 0L; p1[0] = 10; p2[0] = 20; p1[1] = 100; p2[1] = 200; p1[2] = 11; p2[2] = 14;

SQLSetStmtAttr(stmt, SQL_ATTR_PARAMSET_SIZE, 3); // <--- array binding

SQLBindParameter(stmt, 1, p1 ..);

SQLBindParameter(stmt, 2, p2 ..);

SQLExecDirect(stmt,

(SQLCHAR *)"DELETE FROM T1 WHERE I1>? AND I1<?”,

SQL_NTS); do {

SQLRowCount(stmt, &rowcount); printf("%d\n", rowcount); totalRowcount += rowcount; rc = SQLMoreResults(stmt);

} while (rc != SQL_NO_DATA);

259 Upgrade

Other Changes printf(“totalRowcount = %d\n”, totalRowCount);

Execution Results

9 => This is affected row count of DELETE FROM T1 WHERE I1>10 AND I1<20

199 => This is affected row count of DELETE FROM T1 WHERE I1>100 AND I1<200

0 => This is affected row count of DELETE FROM T1 WHERE I1>11 AND I1<14

(No record exists because it is deleted by the first execution.)

208 => This is the total of affected row counts

Each execution result of syntax the argument indicates is created, and then sent to ODBC-CLI. When multiple results are created like this, each data can move for next result with SQLMoreResults() and have its result with SQLRowCount().

If you sum up 3results above in Altibase4, SQLRowCount() returns 208.

If you want same results in Altibase 5 as in Altibase 4, you may execute SQLMoreResults() repeatedly until it returns SQL_NO_DATA, and then add this result to result of SQLRowCount().

Unlimited Array Execute, Array Fetch

Altibase doesn’t have restrictions on Array Execute and Array Fetch as buffer size.

Therefore, you can bind array in the allocated memory and can use CM_BUFF_SIZE no more.

Unavailable Properties

Batch Processing Mode

You can’t use batch keyword of connection string and SQL_ATTR_BATCH.

SQL_ATTR_MAX_ROWS

This indicates to specify the number of prefetched row for better performance in Altibase4. However, this property is similar to LIMIT of SELECT statement following ODBC. This option isn’t available for ODBC-CLI of Altibase.

Therefore, if you specify property above as SQLSetStmtAttr(), this asks your attention because error occurs like ‘Optional feature not implemented’.

ODBC User’s Manual 260

Index

B

Basic Programming Steps

9

Binding Parameters

203

C

C Data Types

222

Converting C Data into SQL Data types

224

Converting SQL Data into C Data Types

223

D

Data Type

243

E

Example of Procedure test Program 217

F

Function Conformance Level

239

Function Overview

177

L

Limitation on ALTER SESSION statements 257

LOB

251

LOB Data Types

176

M

Managing Diagnosis Messages

6

O

ODBC Error Codes

227

Open Database Connectivity

2

P

Programing Considerations

203

S

Sample of Simple Basic Program

204

Sample of Using Metadata 210

SQL Data Types

221

SQLAllocConnect

18

SQLAllocEnv

20

SQLAllocHandle

22

SQLAllocStmt

25

SQL_ATTR_MAX_ROWS

260

SQLBindCol

27

SQLBindFileToCol

178

SQLBindFileToParam

183

SQLBindParameter

33

,

255

SQL_BIT 243

261

SQL_BYTE

249

SQLCloseCursor

31

,

255

SQLColAttribute

42

SQLColumns

46

SQLConnect

50

SQLDescribeCol

52

SQLDescribeParam

55

SQLDisconnect

58

SQLDriverConnect

60

SQLEndTran

65

SQLError

67

SQLExecDirect

69

SQLExecute

71

SQLFetch

74

SQLFetchScroll

78

SQLForeignKeys

80

SQLFreeConnect

84

SQLFreeEnv

86

SQLFreeHandle

87

SQLFreeLob

201

SQLFreeStmt

89

SQLGetConnectAttr

91

SQLGetData

94

SQLGetDescField

98

SQLGetDescRec

100

SQLGetDiagField

102

SQLGetDiagRec

104

SQLGetEnvAttr

106

SQLGetFunctions

108

SQLGetInfo

110

SQLGetLob

191

SQLGetLobLength

188

SQLGetPlan

112

SQLGetStmtAttr

113

SQLGetTypeInfo

115

SQLMoreResult

118

SQLMoreResults()

258

SQLNativeSql

119

SQL_NIBBLE 247

SQLNumParams

121

SQLNumResultCols

123

SQLParamData

125

SQLParamData()

256

SQLPrepare

127

SQLPrimaryKeys

130

SQLProcedureColumns

133

SQLProcedures

137

SQLPutData

140

SQLPutData()

256

SQLPutLob

195

SQLRowCount

142

SQLRowCount()

258

SQLSetConnectAttr

144

SQLSetDescField

147

SQLSetEnvAttr

149

SQLSetStmtAttr

151

SQLStatistics

162

SQLTablePrivileges

166

SQLTables

169

SQLTransact

173

SQL_TYPE_TIMESTAMP

251

SQL_VARBIT 243

State Transition Tables

237

Statement State Transition-related Errors

230

StrLen_or_IndPtr

255

U

Using SQLFreeStmt() function

204

Using the ODBC

4

Using Windows ODBC versus Using UNIX ODBC

7

262

advertisement

advertisement

Table of contents