embulk-output-sqlserver 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -3
- data/classpath/{embulk-output-jdbc-0.5.0.jar → embulk-output-jdbc-0.5.1.jar} +0 -0
- data/classpath/embulk-output-sqlserver-0.5.1.jar +0 -0
- data/src/main/java/org/embulk/output/SQLServerOutputPlugin.java +22 -4
- data/src/main/java/org/embulk/output/sqlserver/InsertMethod.java +32 -0
- data/src/main/java/org/embulk/output/sqlserver/NativeBatchInsert.java +247 -0
- data/src/main/java/org/embulk/output/sqlserver/SmallDateTimeFormat.java +31 -0
- data/src/main/java/org/embulk/output/sqlserver/nativeclient/NativeClient.java +33 -0
- data/src/main/java/org/embulk/output/sqlserver/nativeclient/NativeClientWrapper.java +442 -0
- data/src/main/java/org/embulk/output/sqlserver/nativeclient/ODBC.java +47 -0
- data/src/test/java/org/embulk/output/sqlserver/SQLServerOutputPluginTest.java +174 -10
- data/src/test/resources/sqlserver/data/test2/test2.csv +2 -0
- data/src/test/resources/sqlserver/data/test3/test3.csv +2 -0
- data/src/test/resources/sqlserver/data/test4/test4.csv +2 -0
- data/src/test/resources/sqlserver/data/test5/test5.csv +2 -0
- data/src/test/resources/sqlserver/yml/test-native-date.yml +26 -0
- data/src/test/resources/sqlserver/yml/test-native-decimal.yml +25 -0
- data/src/test/resources/sqlserver/yml/test-native-integer.yml +24 -0
- data/src/test/resources/sqlserver/yml/test-native-string.yml +25 -0
- data/src/test/resources/sqlserver/yml/test-native.yml +44 -0
- metadata +19 -4
- data/classpath/embulk-output-sqlserver-0.5.0.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 107530637391bd44da5f7291004ccef1e1ba0a3b
|
4
|
+
data.tar.gz: a89e2a72c151e984261519e31d879d5449db9060
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6a2ce12e01cbe02743d0ca42de24bf1105ab3ff40ab333cf56f198877ca967577792af1f8b3d6ee0fdaae02894788b7aef66a6aabed86db0c99883459c7b6f5
|
7
|
+
data.tar.gz: 96aeaf1f4c005375a4ce991f6dc9eef502bc896aa3ddb69ed2c492c34809e1b5468726a71adbc7d793a8895988e442db87ff9d3e88fefb8eb9ad6d0a6d7ddfd8
|
data/README.md
CHANGED
@@ -5,8 +5,8 @@ SQL Server output plugins for Embulk loads records to SQL Server.
|
|
5
5
|
## Overview
|
6
6
|
|
7
7
|
* **Plugin type**: output
|
8
|
-
* **Load all or nothing**: depnds on the mode. see
|
9
|
-
* **Resume supported**: depnds on the mode. see
|
8
|
+
* **Load all or nothing**: depnds on the mode. see below.
|
9
|
+
* **Resume supported**: depnds on the mode. see below.
|
10
10
|
|
11
11
|
## Configuration
|
12
12
|
|
@@ -25,7 +25,8 @@ embulk "-J-Djava.library.path=C:\drivers" run input-sqlserver.yml
|
|
25
25
|
- **url**: URL of the JDBC connection (string, optional)
|
26
26
|
- **table**: destination table name (string, required)
|
27
27
|
- **options**: extra connection properties (hash, default: {})
|
28
|
-
- **mode**: "insert", "insert_direct", "truncate_insert" or "replace". See
|
28
|
+
- **mode**: "insert", "insert_direct", "truncate_insert" or "replace". See below. (string, required)
|
29
|
+
- **insert_method**: see below
|
29
30
|
- **batch_size**: size of a single batch insert (integer, default: 16777216)
|
30
31
|
- **default_timezone**: If input column type (embulk type) is timestamp, this plugin needs to format the timestamp into a SQL string. This default_timezone option is used to control the timezone. You can overwrite timezone for each columns using column_options option. (string, default: `UTC`)
|
31
32
|
- **column_options**: advanced: a key-value pairs where key is a column name and value is options for the column.
|
@@ -53,6 +54,15 @@ embulk "-J-Djava.library.path=C:\drivers" run input-sqlserver.yml
|
|
53
54
|
* Transactional: No. If fails, the target table could be dropped (because SQL Server can't rollback DDL).
|
54
55
|
* Resumable: No.
|
55
56
|
|
57
|
+
### Insert methods
|
58
|
+
|
59
|
+
insert_method supports three options.
|
60
|
+
|
61
|
+
"normal" means normal insert (default). It requires SQL Server JDBC driver.
|
62
|
+
|
63
|
+
"native" means bulk insert using native client. It is faster than "normal".
|
64
|
+
It requires both SQL Server JDBC driver and SQL Server Native Client (11.0).
|
65
|
+
|
56
66
|
### Example
|
57
67
|
|
58
68
|
```yaml
|
@@ -81,6 +91,7 @@ out:
|
|
81
91
|
database: my_database
|
82
92
|
table: my_table
|
83
93
|
mode: insert_direct
|
94
|
+
insert_method: native
|
84
95
|
column_options:
|
85
96
|
my_col_1: {type: 'TEXT'}
|
86
97
|
my_col_3: {type: 'INT NOT NULL'}
|
Binary file
|
Binary file
|
@@ -11,6 +11,8 @@ import org.embulk.output.jdbc.AbstractJdbcOutputPlugin;
|
|
11
11
|
import org.embulk.output.jdbc.BatchInsert;
|
12
12
|
import org.embulk.output.jdbc.StandardBatchInsert;
|
13
13
|
import org.embulk.output.jdbc.setter.ColumnSetterFactory;
|
14
|
+
import org.embulk.output.sqlserver.InsertMethod;
|
15
|
+
import org.embulk.output.sqlserver.NativeBatchInsert;
|
14
16
|
import org.embulk.output.sqlserver.SQLServerOutputConnector;
|
15
17
|
import org.embulk.output.sqlserver.setter.SQLServerColumnSetterFactory;
|
16
18
|
import org.joda.time.DateTimeZone;
|
@@ -60,6 +62,9 @@ public class SQLServerOutputPlugin
|
|
60
62
|
@ConfigDefault("\"\"")
|
61
63
|
public Optional<String> getPassword();
|
62
64
|
|
65
|
+
@Config("insert_method")
|
66
|
+
@ConfigDefault("\"normal\"")
|
67
|
+
public InsertMethod getInsertMethod();
|
63
68
|
}
|
64
69
|
|
65
70
|
@Override
|
@@ -88,6 +93,10 @@ public class SQLServerOutputPlugin
|
|
88
93
|
|
89
94
|
String url;
|
90
95
|
if (sqlServerTask.getUrl().isPresent()) {
|
96
|
+
if (sqlServerTask.getInsertMethod() == InsertMethod.NATIVE) {
|
97
|
+
throw new IllegalArgumentException("Cannot set 'url' when 'insert_method' is 'native'.");
|
98
|
+
}
|
99
|
+
|
91
100
|
if (sqlServerTask.getHost().isPresent()
|
92
101
|
|| sqlServerTask.getInstance().isPresent()
|
93
102
|
|| sqlServerTask.getDatabase().isPresent()
|
@@ -104,8 +113,8 @@ public class SQLServerOutputPlugin
|
|
104
113
|
}
|
105
114
|
StringBuilder urlBuilder = new StringBuilder();
|
106
115
|
if (sqlServerTask.getInstance().isPresent()) {
|
107
|
-
urlBuilder.append(String.format("jdbc:sqlserver://%s\\%s
|
108
|
-
sqlServerTask.getHost().get(), sqlServerTask.getInstance().get()
|
116
|
+
urlBuilder.append(String.format("jdbc:sqlserver://%s\\%s",
|
117
|
+
sqlServerTask.getHost().get(), sqlServerTask.getInstance().get()));
|
109
118
|
} else {
|
110
119
|
urlBuilder.append(String.format("jdbc:sqlserver://%s:%d",
|
111
120
|
sqlServerTask.getHost().get(), sqlServerTask.getPort()));
|
@@ -130,9 +139,13 @@ public class SQLServerOutputPlugin
|
|
130
139
|
Properties props = new Properties();
|
131
140
|
props.putAll(sqlServerTask.getOptions());
|
132
141
|
|
133
|
-
|
142
|
+
if (sqlServerTask.getUser().isPresent()) {
|
143
|
+
props.setProperty("user", sqlServerTask.getUser().get());
|
144
|
+
}
|
134
145
|
logger.info("Connecting to {} options {}", url, props);
|
135
|
-
|
146
|
+
if (sqlServerTask.getPassword().isPresent()) {
|
147
|
+
props.setProperty("password", sqlServerTask.getPassword().get());
|
148
|
+
}
|
136
149
|
|
137
150
|
return new SQLServerOutputConnector(url, props, null);
|
138
151
|
}
|
@@ -140,6 +153,11 @@ public class SQLServerOutputPlugin
|
|
140
153
|
@Override
|
141
154
|
protected BatchInsert newBatchInsert(PluginTask task, Optional<List<String>> mergeKeys) throws IOException, SQLException
|
142
155
|
{
|
156
|
+
SQLServerPluginTask sqlServerTask = (SQLServerPluginTask) task;
|
157
|
+
if (sqlServerTask.getInsertMethod() == InsertMethod.NATIVE) {
|
158
|
+
return new NativeBatchInsert(sqlServerTask.getHost().get(), sqlServerTask.getPort(), sqlServerTask.getInstance(),
|
159
|
+
sqlServerTask.getDatabase().get(), sqlServerTask.getUser(), sqlServerTask.getPassword());
|
160
|
+
}
|
143
161
|
return new StandardBatchInsert(getConnector(task, true), mergeKeys);
|
144
162
|
}
|
145
163
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
package org.embulk.output.sqlserver;
|
2
|
+
|
3
|
+
import java.util.Locale;
|
4
|
+
|
5
|
+
import org.embulk.config.ConfigException;
|
6
|
+
|
7
|
+
import com.fasterxml.jackson.annotation.JsonCreator;
|
8
|
+
import com.fasterxml.jackson.annotation.JsonValue;
|
9
|
+
|
10
|
+
public enum InsertMethod
|
11
|
+
{
|
12
|
+
NORMAL,
|
13
|
+
NATIVE;
|
14
|
+
|
15
|
+
@JsonValue
|
16
|
+
@Override
|
17
|
+
public String toString()
|
18
|
+
{
|
19
|
+
return name().toLowerCase(Locale.ENGLISH);
|
20
|
+
}
|
21
|
+
|
22
|
+
@JsonCreator
|
23
|
+
public static InsertMethod fromString(String value)
|
24
|
+
{
|
25
|
+
for (InsertMethod insertMethod : InsertMethod.values()) {
|
26
|
+
if (insertMethod.toString().equals(value)) {
|
27
|
+
return insertMethod;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
throw new ConfigException(String.format("Unknown insert_method '%s'.", value));
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,247 @@
|
|
1
|
+
package org.embulk.output.sqlserver;
|
2
|
+
|
3
|
+
import java.io.IOException;
|
4
|
+
import java.math.BigDecimal;
|
5
|
+
import java.sql.SQLException;
|
6
|
+
import java.sql.Types;
|
7
|
+
import java.text.DateFormat;
|
8
|
+
import java.text.SimpleDateFormat;
|
9
|
+
import java.util.Calendar;
|
10
|
+
|
11
|
+
import org.embulk.output.jdbc.BatchInsert;
|
12
|
+
import org.embulk.output.jdbc.JdbcColumn;
|
13
|
+
import org.embulk.output.jdbc.JdbcSchema;
|
14
|
+
import org.embulk.output.jdbc.StandardBatchInsert;
|
15
|
+
import org.embulk.output.jdbc.TimestampFormat;
|
16
|
+
import org.embulk.output.sqlserver.nativeclient.NativeClientWrapper;
|
17
|
+
import org.embulk.spi.Exec;
|
18
|
+
import org.embulk.spi.time.Timestamp;
|
19
|
+
import org.slf4j.Logger;
|
20
|
+
|
21
|
+
import com.google.common.base.Optional;
|
22
|
+
|
23
|
+
public class NativeBatchInsert implements BatchInsert
|
24
|
+
{
|
25
|
+
private final Logger logger = Exec.getLogger(StandardBatchInsert.class);
|
26
|
+
|
27
|
+
private NativeClientWrapper client = new NativeClientWrapper();
|
28
|
+
|
29
|
+
private final String server;
|
30
|
+
private final int port;
|
31
|
+
private final Optional<String> instance;
|
32
|
+
private final String database;
|
33
|
+
private final Optional<String> user;
|
34
|
+
private final Optional<String> password;
|
35
|
+
|
36
|
+
private int batchWeight;
|
37
|
+
private int batchRows;
|
38
|
+
private long totalRows;
|
39
|
+
|
40
|
+
private int columnCount;
|
41
|
+
private int lastColumnIndex;
|
42
|
+
|
43
|
+
private DateFormat[] formats;
|
44
|
+
|
45
|
+
|
46
|
+
public NativeBatchInsert(String server, int port, Optional<String> instance,
|
47
|
+
String database, Optional<String> user, Optional<String> password)
|
48
|
+
{
|
49
|
+
this.server = server;
|
50
|
+
this.port = port;
|
51
|
+
this.instance = instance;
|
52
|
+
this.database = database;
|
53
|
+
this.user = user;
|
54
|
+
this.password = password;
|
55
|
+
|
56
|
+
lastColumnIndex = 0;
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
@Override
|
61
|
+
public void prepare(String loadTable, JdbcSchema insertSchema) throws SQLException
|
62
|
+
{
|
63
|
+
columnCount = insertSchema.getCount();
|
64
|
+
client.open(server, port, instance, database, user, password, loadTable);
|
65
|
+
|
66
|
+
formats = new DateFormat[insertSchema.getCount()];
|
67
|
+
for (int i = 0; i < insertSchema.getCount(); i++) {
|
68
|
+
JdbcColumn column = insertSchema.getColumn(i);
|
69
|
+
switch (column.getSqlType()) {
|
70
|
+
case Types.DATE:
|
71
|
+
formats[i] = new SimpleDateFormat("yyyy-MM-dd");
|
72
|
+
break;
|
73
|
+
|
74
|
+
case Types.TIME:
|
75
|
+
formats[i] = new TimestampFormat("HH:mm:ss", column.getScaleTypeParameter());
|
76
|
+
break;
|
77
|
+
|
78
|
+
case Types.TIMESTAMP:
|
79
|
+
if (column.getSimpleTypeName().equals("SMALLDATETIME")) {
|
80
|
+
formats[i] = new SmallDateTimeFormat("yyyy-MM-dd HH:mm:ss");
|
81
|
+
} else {
|
82
|
+
formats[i] = new TimestampFormat("yyyy-MM-dd HH:mm:ss", column.getScaleTypeParameter());
|
83
|
+
}
|
84
|
+
break;
|
85
|
+
|
86
|
+
default:
|
87
|
+
break;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
@Override
|
93
|
+
public int getBatchWeight()
|
94
|
+
{
|
95
|
+
return batchWeight;
|
96
|
+
}
|
97
|
+
|
98
|
+
@Override
|
99
|
+
public void add() throws IOException, SQLException
|
100
|
+
{
|
101
|
+
client.sendRow();
|
102
|
+
|
103
|
+
batchRows++;
|
104
|
+
batchWeight += 32; // add weight as overhead of each rows
|
105
|
+
}
|
106
|
+
|
107
|
+
private int nextColumnIndex()
|
108
|
+
{
|
109
|
+
int nextColumnIndex = lastColumnIndex + 1;
|
110
|
+
if (nextColumnIndex == columnCount) {
|
111
|
+
lastColumnIndex = 0;
|
112
|
+
} else {
|
113
|
+
lastColumnIndex++;
|
114
|
+
}
|
115
|
+
return nextColumnIndex;
|
116
|
+
}
|
117
|
+
|
118
|
+
@Override
|
119
|
+
public void setNull(int sqlType) throws IOException, SQLException
|
120
|
+
{
|
121
|
+
batchWeight += client.bindNull(nextColumnIndex());
|
122
|
+
}
|
123
|
+
|
124
|
+
@Override
|
125
|
+
public void setBoolean(boolean v) throws IOException, SQLException
|
126
|
+
{
|
127
|
+
batchWeight += client.bindValue(nextColumnIndex(), v);
|
128
|
+
}
|
129
|
+
|
130
|
+
@Override
|
131
|
+
public void setByte(byte v) throws IOException, SQLException
|
132
|
+
{
|
133
|
+
batchWeight += client.bindValue(nextColumnIndex(), v);
|
134
|
+
}
|
135
|
+
|
136
|
+
@Override
|
137
|
+
public void setShort(short v) throws IOException, SQLException
|
138
|
+
{
|
139
|
+
batchWeight += client.bindValue(nextColumnIndex(), v);
|
140
|
+
}
|
141
|
+
|
142
|
+
@Override
|
143
|
+
public void setInt(int v) throws IOException, SQLException
|
144
|
+
{
|
145
|
+
batchWeight += client.bindValue(nextColumnIndex(), v);
|
146
|
+
}
|
147
|
+
|
148
|
+
@Override
|
149
|
+
public void setLong(long v) throws IOException, SQLException
|
150
|
+
{
|
151
|
+
batchWeight += client.bindValue(nextColumnIndex(), v);
|
152
|
+
}
|
153
|
+
|
154
|
+
@Override
|
155
|
+
public void setFloat(float v) throws IOException, SQLException
|
156
|
+
{
|
157
|
+
batchWeight += client.bindValue(nextColumnIndex(), v);
|
158
|
+
}
|
159
|
+
|
160
|
+
@Override
|
161
|
+
public void setDouble(double v) throws IOException, SQLException
|
162
|
+
{
|
163
|
+
batchWeight += client.bindValue(nextColumnIndex(), v);
|
164
|
+
}
|
165
|
+
|
166
|
+
@Override
|
167
|
+
public void setBigDecimal(BigDecimal v) throws IOException, SQLException
|
168
|
+
{
|
169
|
+
batchWeight += client.bindValue(nextColumnIndex(), v.toPlainString());
|
170
|
+
}
|
171
|
+
|
172
|
+
@Override
|
173
|
+
public void setString(String v) throws IOException, SQLException
|
174
|
+
{
|
175
|
+
batchWeight += client.bindValue(nextColumnIndex(), v);
|
176
|
+
}
|
177
|
+
|
178
|
+
@Override
|
179
|
+
public void setNString(String v) throws IOException, SQLException
|
180
|
+
{
|
181
|
+
batchWeight += client.bindValue(nextColumnIndex(), v);
|
182
|
+
}
|
183
|
+
|
184
|
+
@Override
|
185
|
+
public void setBytes(byte[] v) throws IOException, SQLException
|
186
|
+
{
|
187
|
+
throw new SQLException("Unsupported");
|
188
|
+
}
|
189
|
+
|
190
|
+
@Override
|
191
|
+
public void setSqlDate(Timestamp v, Calendar cal) throws IOException, SQLException
|
192
|
+
{
|
193
|
+
setSqlTimestamp(v, cal);
|
194
|
+
}
|
195
|
+
|
196
|
+
@Override
|
197
|
+
public void setSqlTime(Timestamp v, Calendar cal) throws IOException, SQLException
|
198
|
+
{
|
199
|
+
setSqlTimestamp(v, cal);
|
200
|
+
}
|
201
|
+
|
202
|
+
@Override
|
203
|
+
public void setSqlTimestamp(Timestamp v, Calendar cal) throws IOException, SQLException
|
204
|
+
{
|
205
|
+
int columnIndex = nextColumnIndex();
|
206
|
+
DateFormat format = formats[columnIndex - 1];
|
207
|
+
format.setCalendar(cal);
|
208
|
+
|
209
|
+
java.sql.Timestamp timestamp = new java.sql.Timestamp(v.toEpochMilli());
|
210
|
+
timestamp.setNanos(v.getNano());
|
211
|
+
|
212
|
+
batchWeight += client.bindValue(columnIndex, format.format(timestamp));
|
213
|
+
}
|
214
|
+
|
215
|
+
@Override
|
216
|
+
public void flush() throws IOException, SQLException
|
217
|
+
{
|
218
|
+
logger.info(String.format("Loading %,d rows", batchRows));
|
219
|
+
long startTime = System.currentTimeMillis();
|
220
|
+
|
221
|
+
client.commit(false);
|
222
|
+
|
223
|
+
double seconds = (System.currentTimeMillis() - startTime) / 1000.0;
|
224
|
+
totalRows += batchRows;
|
225
|
+
|
226
|
+
logger.info(String.format("> %.2f seconds (loaded %,d rows in total)", seconds, totalRows));
|
227
|
+
|
228
|
+
batchRows = 0;
|
229
|
+
batchWeight = 0;
|
230
|
+
}
|
231
|
+
|
232
|
+
@Override
|
233
|
+
public void finish() throws IOException, SQLException
|
234
|
+
{
|
235
|
+
if (getBatchWeight() != 0) {
|
236
|
+
flush();
|
237
|
+
}
|
238
|
+
client.commit(true);
|
239
|
+
}
|
240
|
+
|
241
|
+
@Override
|
242
|
+
public void close() throws IOException, SQLException
|
243
|
+
{
|
244
|
+
client.close();
|
245
|
+
}
|
246
|
+
|
247
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
package org.embulk.output.sqlserver;
|
2
|
+
|
3
|
+
import java.text.FieldPosition;
|
4
|
+
import java.text.SimpleDateFormat;
|
5
|
+
import java.util.Date;
|
6
|
+
|
7
|
+
|
8
|
+
public class SmallDateTimeFormat extends SimpleDateFormat
|
9
|
+
{
|
10
|
+
public SmallDateTimeFormat(String pattern)
|
11
|
+
{
|
12
|
+
super(pattern);
|
13
|
+
}
|
14
|
+
|
15
|
+
@Override
|
16
|
+
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos)
|
17
|
+
{
|
18
|
+
long time = date.getTime();
|
19
|
+
|
20
|
+
// round seconds
|
21
|
+
long underMinutes = time % 60000;
|
22
|
+
if (underMinutes < 30000) {
|
23
|
+
time -= underMinutes;
|
24
|
+
} else {
|
25
|
+
time += 60000 - underMinutes;
|
26
|
+
}
|
27
|
+
|
28
|
+
return super.format(new Date(time), toAppendTo, pos);
|
29
|
+
}
|
30
|
+
|
31
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
package org.embulk.output.sqlserver.nativeclient;
|
2
|
+
|
3
|
+
import jnr.ffi.Pointer;
|
4
|
+
|
5
|
+
public interface NativeClient
|
6
|
+
{
|
7
|
+
static int SQL_NULL_DATA = -1;
|
8
|
+
static int SQLCHARACTER = 0x2F;
|
9
|
+
static int SQLINT1 = 0x30;
|
10
|
+
static int SQLBIT = 0x32;
|
11
|
+
static int SQLINT2 = 0x34;
|
12
|
+
static int SQLINT4 = 0x38;
|
13
|
+
static int SQLFLT8 = 0x3E;
|
14
|
+
static int SQLFLT4 = 0x3B;
|
15
|
+
static int SQLINT8 = 0x7F;
|
16
|
+
|
17
|
+
static short FAIL = 0;
|
18
|
+
static short SUCCEED = 1;
|
19
|
+
static int DB_IN = 1;
|
20
|
+
|
21
|
+
short bcp_initW(Pointer hdbc, Pointer szTable, Pointer szDataFile, Pointer szErrorFile, int eDirection);
|
22
|
+
|
23
|
+
short bcp_bind(Pointer hdbc,
|
24
|
+
Pointer pData, int cbIndicator, int cbData,
|
25
|
+
Pointer pTerm, int cbTerm,
|
26
|
+
int eDataType, int idxServerCol);
|
27
|
+
|
28
|
+
short bcp_sendrow(Pointer hdbc);
|
29
|
+
|
30
|
+
int bcp_batch(Pointer hdbc);
|
31
|
+
|
32
|
+
int bcp_done(Pointer hdbc);
|
33
|
+
}
|