1
-
2
- /* Module: bind.c
3
- *
4
- * Description: This module contains routines related to binding
5
- * columns and parameters.
6
- *
7
- * Classes: BindInfoClass, ParameterInfoClass
8
- *
9
- * API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams,
10
- * SQLParamOptions(NI)
11
- *
12
- * Comments: See "notice.txt" for copyright and license information.
13
- *
14
- */
1
+
2
+ /* Module: bind.c
3
+ *
4
+ * Description: This module contains routines related to binding
5
+ * columns and parameters.
6
+ *
7
+ * Classes: BindInfoClass, ParameterInfoClass
8
+ *
9
+ * API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams,
10
+ * SQLParamOptions(NI)
11
+ *
12
+ * Comments: See "notice.txt" for copyright and license information.
13
+ *
14
+ */
15
15
#include "bind.h"
16
16
#include "environ.h"
17
17
#include "statement.h"
18
18
#include "qresult.h"
19
19
#include "pgtypes.h"
20
20
#include <stdlib.h>
21
21
#include <malloc.h>
22
- #include <sql.h>
23
- #include <sqlext.h>
22
+ #include <sql.h>
23
+ #include <sqlext.h>
24
24
25
25
// Bind parameters on a statement handle
26
26
@@ -77,10 +77,11 @@ StatementClass *stmt = (StatementClass *) hstmt;
77
77
stmt -> parameters [i ].CType = 0 ;
78
78
stmt -> parameters [i ].SQLType = 0 ;
79
79
stmt -> parameters [i ].precision = 0 ;
80
- stmt -> parameters [i ].scale = 0 ;
81
- stmt -> parameters [i ].data_at_exec = FALSE;
82
- stmt -> parameters [i ].EXEC_used = NULL ;
83
- stmt -> parameters [i ].EXEC_buffer = NULL ;
80
+ stmt -> parameters [i ].scale = 0 ;
81
+ stmt -> parameters [i ].data_at_exec = FALSE;
82
+ stmt -> parameters [i ].lobj_oid = 0 ;
83
+ stmt -> parameters [i ].EXEC_used = NULL ;
84
+ stmt -> parameters [i ].EXEC_buffer = NULL ;
84
85
}
85
86
}
86
87
@@ -94,26 +95,28 @@ StatementClass *stmt = (StatementClass *) hstmt;
94
95
stmt -> parameters [ipar ].CType = fCType ;
95
96
stmt -> parameters [ipar ].SQLType = fSqlType ;
96
97
stmt -> parameters [ipar ].precision = cbColDef ;
97
- stmt -> parameters [ipar ].scale = ibScale ;
98
-
99
- /* If rebinding a parameter that had data-at-exec stuff in it,
100
- then free that stuff
101
- */
102
- if (stmt -> parameters [ipar ].EXEC_used ) {
103
- free (stmt -> parameters [ipar ].EXEC_used );
104
- stmt -> parameters [ipar ].EXEC_used = NULL ;
105
- }
106
-
107
- if (stmt -> parameters [ipar ].EXEC_buffer ) {
108
- free (stmt -> parameters [ipar ].EXEC_buffer );
109
- stmt -> parameters [ipar ].EXEC_buffer = NULL ;
110
- }
111
-
112
- if (pcbValue && * pcbValue <= SQL_LEN_DATA_AT_EXEC_OFFSET )
113
- stmt -> parameters [ipar ].data_at_exec = TRUE;
114
- else
115
- stmt -> parameters [ipar ].data_at_exec = FALSE;
116
-
98
+ stmt -> parameters [ipar ].scale = ibScale ;
99
+
100
+ /* If rebinding a parameter that had data-at-exec stuff in it,
101
+ then free that stuff
102
+ */
103
+ if (stmt -> parameters [ipar ].EXEC_used ) {
104
+ free (stmt -> parameters [ipar ].EXEC_used );
105
+ stmt -> parameters [ipar ].EXEC_used = NULL ;
106
+ }
107
+
108
+ if (stmt -> parameters [ipar ].EXEC_buffer ) {
109
+ free (stmt -> parameters [ipar ].EXEC_buffer );
110
+ stmt -> parameters [ipar ].EXEC_buffer = NULL ;
111
+ }
112
+
113
+ if (pcbValue && * pcbValue <= SQL_LEN_DATA_AT_EXEC_OFFSET )
114
+ stmt -> parameters [ipar ].data_at_exec = TRUE;
115
+ else
116
+ stmt -> parameters [ipar ].data_at_exec = FALSE;
117
+
118
+ mylog ("SQLBindParamater: ipar = %d, *pcbValue = %d, data_at_exec = %d\n" ,
119
+ ipar , pcbValue ? * pcbValue : -777 , stmt -> parameters [ipar ].data_at_exec );
117
120
118
121
return SQL_SUCCESS ;
119
122
}
@@ -188,6 +191,8 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
188
191
stmt -> bindings [icol ].buffer = rgbValue ;
189
192
stmt -> bindings [icol ].used = pcbValue ;
190
193
stmt -> bindings [icol ].returntype = fCType ;
194
+
195
+ mylog (" bound buffer[%d] = %u\n" , icol , stmt -> bindings [icol ].buffer );
191
196
}
192
197
193
198
return SQL_SUCCESS ;
@@ -228,7 +233,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
228
233
* pibScale = stmt -> parameters [ipar ].scale ;
229
234
230
235
if (pfNullable )
231
- * pfNullable = pgtype_nullable (stmt -> parameters [ipar ].paramType );
236
+ * pfNullable = pgtype_nullable (stmt , stmt -> parameters [ipar ].paramType );
232
237
233
238
return SQL_SUCCESS ;
234
239
}
@@ -247,37 +252,25 @@ RETCODE SQL_API SQLParamOptions(
247
252
248
253
// - - - - - - - - -
249
254
250
- // Returns the number of parameter markers.
255
+ // Returns the number of parameters in an SQL statement
251
256
252
257
RETCODE SQL_API SQLNumParams (
253
258
HSTMT hstmt ,
254
259
SWORD FAR * pcpar )
255
260
{
256
261
StatementClass * stmt = (StatementClass * ) hstmt ;
257
- unsigned int i ;
258
262
259
- // I guess this is the number of actual parameter markers
260
- // in the statement, not the number of parameters that are bound.
261
- // why does this have to be driver-specific?
262
263
263
264
if (!stmt )
264
265
return SQL_INVALID_HANDLE ;
265
266
266
- if (!stmt -> statement ) {
267
- // no statement has been allocated
268
- * pcpar = 0 ;
269
- stmt -> errormsg = "SQLNumParams called with no statement ready." ;
270
- stmt -> errornumber = STMT_SEQUENCE_ERROR ;
271
- return SQL_ERROR ;
272
- } else {
273
- * pcpar = 0 ;
274
- for (i = 0 ; i < strlen (stmt -> statement ); i ++ ) {
275
- if (stmt -> statement [i ] == '?' )
276
- (* pcpar )++ ;
277
- }
267
+ // If the statement does not have parameters, it should just return 0.
278
268
279
- return SQL_SUCCESS ;
269
+ if (pcpar ) {
270
+ * pcpar = stmt -> parameters_allocated ;
280
271
}
272
+
273
+ return SQL_SUCCESS ;
281
274
}
282
275
283
276
/********************************************************************
@@ -309,7 +302,7 @@ extend_bindings(StatementClass *stmt, int num_columns)
309
302
BindInfoClass * new_bindings ;
310
303
int i ;
311
304
312
- mylog ("in extend_bindings\n" );
305
+ mylog ("in extend_bindings: stmt=%u, bindings_allocated=%d, num_columns=%d \n" , stmt , stmt -> bindings_allocated , num_columns );
313
306
314
307
/* if we have too few, allocate room for more, and copy the old */
315
308
/* entries into the new structure */
@@ -325,6 +318,7 @@ int i;
325
318
}
326
319
327
320
stmt -> bindings = new_bindings ; // null indicates error
321
+ stmt -> bindings_allocated = num_columns ;
328
322
329
323
} else {
330
324
/* if we have too many, make sure the extra ones are emptied out */
0 commit comments