15
27
SQL_NUMERIC_STRUCT *num;
18
SQLFreeStmt(Statement, SQL_UNBIND);
19
SQLFreeStmt(Statement, SQL_RESET_PARAMS);
21
32
/* build store procedure to test */
33
Command(Statement, "IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
22
34
sprintf(sbuf, "CREATE PROC spTestProc @i %s OUTPUT AS SELECT @i = CONVERT(%s, '%s')", type, type, value_to_convert);
23
35
Command(Statement, sbuf);
24
36
memset(out_buf, 0, sizeof(out_buf));
40
if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0) != SQL_SUCCESS)
41
ODBC_REPORT_ERROR("SQLSetStmtAttr error");
42
if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0) != SQL_SUCCESS)
43
ODBC_REPORT_ERROR("SQLSetStmtAttr error");
26
46
/* bind parameter */
27
if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, 18, 0, out_buf, sizeof(out_buf), &out_len) !=
29
ODBC_REPORT_ERROR("Unable to bind input parameter");
31
/* call store procedure */
32
if (SQLExecDirect(Statement, "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)
33
ODBC_REPORT_ERROR("Unable to execute store statement");
48
if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
49
sizeof(out_buf), &out_len) != SQL_SUCCESS)
50
ODBC_REPORT_ERROR("Unable to bind output parameter");
52
/* call store procedure */
53
if (SQLExecDirect(Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)
54
ODBC_REPORT_ERROR("Unable to execute store statement");
56
if (prepare_before && SQLPrepare(Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)
57
ODBC_REPORT_ERROR("SQLPrepare() failure!");
59
if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
60
sizeof(out_buf), &out_len) != SQL_SUCCESS)
61
ODBC_REPORT_ERROR("Unable to bind output parameter");
63
if (!prepare_before && SQLPrepare(Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)
64
ODBC_REPORT_ERROR("SQLPrepare() failure!");
66
if (SQLExecute(Statement) != SQL_SUCCESS)
67
ODBC_REPORT_ERROR("SQLExecute() failure!");
68
103
unsigned char out_buf[256];
69
104
SQLLEN out_len = 0;
105
const char *expected = value_to_convert;
106
size_t value_len = strlen(value_to_convert);
71
SQLFreeStmt(Statement, SQL_UNBIND);
72
SQLFreeStmt(Statement, SQL_RESET_PARAMS);
74
111
/* execute a select to get data as wire */
75
sprintf(sbuf, "SELECT CONVERT(%s, '%s')", type, value_to_convert);
112
if ((p = strstr(value_to_convert, " -> ")) != NULL) {
113
value_len = p - value_to_convert;
116
sprintf(sbuf, "SELECT CONVERT(%s, '%.*s')", type, (int) value_len, value_to_convert);
76
117
Command(Statement, sbuf);
77
118
SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
78
if (SQLFetch(Statement) != SQL_SUCCESS)
119
if (!SQL_SUCCEEDED(SQLFetch(Statement)))
79
120
ODBC_REPORT_ERROR("Expected row");
80
121
if (SQLFetch(Statement) != SQL_NO_DATA)
81
122
ODBC_REPORT_ERROR("Row not expected");
83
124
ODBC_REPORT_ERROR("Recordset not expected");
85
126
/* create a table with a column of that type */
86
SQLFreeStmt(Statement, SQL_UNBIND);
87
SQLFreeStmt(Statement, SQL_RESET_PARAMS);
88
128
sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s)", param_type);
89
129
Command(Statement, sbuf);
133
if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0) != SQL_SUCCESS)
134
ODBC_REPORT_ERROR("SQLSetStmtAttr error");
135
if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0) != SQL_SUCCESS)
136
ODBC_REPORT_ERROR("SQLSetStmtAttr error");
91
139
/* insert data using prepared statements */
92
140
sprintf(sbuf, "INSERT INTO #tmp_insert VALUES(?)");
93
if (SQLPrepare(Statement, sbuf, SQL_NTS) != SQL_SUCCESS)
94
ODBC_REPORT_ERROR("SQLPrepare() failure!");
97
if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len) !=
99
ODBC_REPORT_ERROR("Unable to bind input parameter");
101
if (SQLExecute(Statement) != SQL_SUCCESS)
102
ODBC_REPORT_ERROR("SQLExecute() failure!");
145
if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len) !=
147
ODBC_REPORT_ERROR("Unable to bind input parameter");
149
rc = SQLExecDirect(Statement, (SQLCHAR *) sbuf, SQL_NTS);
150
if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
151
ODBC_REPORT_ERROR("SQLExecDirect() failure!");
155
if (prepare_before && SQLPrepare(Statement, (SQLCHAR *) sbuf, SQL_NTS) != SQL_SUCCESS)
156
ODBC_REPORT_ERROR("SQLPrepare() failure!");
159
if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len) !=
161
ODBC_REPORT_ERROR("Unable to bind input parameter");
163
if (!prepare_before && SQLPrepare(Statement, (SQLCHAR *) sbuf, SQL_NTS) != SQL_SUCCESS)
164
ODBC_REPORT_ERROR("SQLPrepare() failure!");
166
rc = SQLExecute(Statement);
167
if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
168
ODBC_REPORT_ERROR("SQLExecute() failure!");
104
171
/* check is row is present */
105
SQLFreeStmt(Statement, SQL_UNBIND);
106
SQLFreeStmt(Statement, SQL_RESET_PARAMS);
107
sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, '%s')", param_type, value_to_convert);
173
sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, '%s')", param_type, expected);
108
174
Command(Statement, sbuf);
110
176
if (SQLFetch(Statement) != SQL_SUCCESS)
116
182
Command(Statement, "DROP TABLE #tmp_insert");
120
main(int argc, char *argv[])
185
static int big_endian = 1;
186
static char version[32];
126
if (CommandWithResult(Statement, "drop proc spTestProc") != SQL_SUCCESS)
127
printf("Unable to execute statement\n");
129
if (((char *) &big_endian)[0] == 1)
198
printf("use_cursors %d exec_direct %d prepare_before %d\n", use_cursors, exec_direct, prepare_before);
132
200
/* FIXME why should return 38 0 as precision and scale ?? correct ?? */
133
202
Test("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "18 0 1 7B");
203
Test("DECIMAL(18,2)", "123", SQL_C_NUMERIC, SQL_DECIMAL, "18 0 1 7B");
205
Test("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "38 0 1 7B");
134
206
TestInput(SQL_C_LONG, "INTEGER", SQL_VARCHAR, "VARCHAR(20)", "12345");
135
207
/* MS driver behavior for output parameters is different */
136
208
if (driver_is_freetds())
137
209
Test("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "333133323333");
139
211
Test("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "313233");
212
/* FIXME our driver ignore precision for date */
140
214
Test("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, big_endian ? "0000949700FBAA2C" : "979400002CAAFB00");
141
215
Test("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP,
142
216
big_endian ? "0000949700FB9640" : "979400004096FB00");
217
TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34");
219
/* test timestamp millisecond round off */
220
TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.001 -> 2005-07-22 09:51:34.000");
221
TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.002 -> 2005-07-22 09:51:34.003");
222
TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.003 -> 2005-07-22 09:51:34.003");
223
TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.004 -> 2005-07-22 09:51:34.003");
224
TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.005 -> 2005-07-22 09:51:34.007");
225
TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.006 -> 2005-07-22 09:51:34.007");
227
/* FIXME on ms driver first SQLFetch return SUCCESS_WITH_INFO for truncation error */
228
TestInput(SQL_C_TYPE_DATE, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 13:02:03 -> 2005-07-22 00:00:00");
230
/* replace date information with current date */
232
ltime = localtime(&curr_time);
233
y = ltime->tm_year + 1900;
234
m = ltime->tm_mon + 1;
236
/* server concept of data can be different so try ask to server */
237
Command(Statement, "SELECT GETDATE()");
238
SQLBindCol(Statement, 1, SQL_C_CHAR, date, sizeof(date), NULL);
239
if (SQLFetch(Statement) == SQL_SUCCESS) {
241
if (sscanf(date, "%d-%d-%d", &a, &b, &c) == 3) {
248
SQLMoreResults(Statement);
249
SQLFreeStmt(Statement, SQL_UNBIND);
250
sprintf(buf, "2003-07-22 13:02:03 -> %04d-%02d-%02d 13:02:03", (int) y, (int) m, (int) d);
251
TestInput(SQL_C_TYPE_TIME, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", buf);
253
TestInput(SQL_C_FLOAT, "FLOAT", SQL_REAL, "FLOAT", "1234.25");
254
TestInput(SQL_C_DOUBLE, "REAL", SQL_REAL, "FLOAT", "-1234.25");
255
TestInput(SQL_C_FLOAT, "REAL", SQL_REAL, "FLOAT", "1234.25");
256
TestInput(SQL_C_DOUBLE, "FLOAT", SQL_REAL, "FLOAT", "-1234.25");
257
TestInput(SQL_C_FLOAT, "FLOAT", SQL_FLOAT, "FLOAT", "1234.25");
258
TestInput(SQL_C_DOUBLE, "REAL", SQL_FLOAT, "FLOAT", "-1234.25");
259
TestInput(SQL_C_FLOAT, "FLOAT", SQL_DOUBLE, "FLOAT", "1234.25");
260
TestInput(SQL_C_DOUBLE, "REAL", SQL_DOUBLE, "FLOAT", "-1234.25");
262
TestInput(SQL_C_UTINYINT, "TINYINT", SQL_TINYINT, "TINYINT", "231");
264
TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_NUMERIC, "NUMERIC(20,3)", "765432.2 -> 765432");
266
TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "0");
267
TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "1");
269
TestInput(SQL_C_DOUBLE, "MONEY", SQL_DOUBLE, "MONEY", "123.34");
271
/* TODO some Sybase versions */
272
if (db_is_microsoft() && strncmp(version, "08.00.", 6) == 0) {
273
Test("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
274
TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
279
main(int argc, char *argv[])
281
SQLSMALLINT version_len;
283
use_odbc_version3 = 1;
286
memset(version, 0, sizeof(version));
287
SQLGetInfo(Connection, SQL_DBMS_VER, version, sizeof(version), &version_len);
289
if (((char *) &big_endian)[0] == 1)
292
for (use_cursors = 0; use_cursors <= 1; ++use_cursors) {
294
if (!tds_no_dm || !driver_is_freetds())
146
312
printf("Done successfully!\n");