By executing a separate SQL statement at each point, you are doing as many database round-trips as there are points to insert. Each round-trip incurs a communication latency (especially if the database is not local) as well as some bookkeeping costs at the level of the DBMS.
The crude and not very scalable, but database-agnostic way to perform multiple inserts within only one database round-trip is to simply pack multiple INSERT statements into a single DbCommand object.
Assuming your table looks similar to this (use your DBMS-specific types as appropriate)...
CREATE TABLE YOUR_TABLE(
INDEX_X int NOT NULL,
INDEX_Y int NOT NULL,
VALUE numeric(18, 4) NOT NULL,
PRIMARY KEY ( INDEX_X, INDEX_Y )
)
...here is one way to do it:
class Program {
static void Main(string[] args) {
double[,] pt = {
{ 0.3, 0.2, 0.1, 0.8 },
{ 0.2, 0.5, 0.5, 0.1 },
{ 0.1, 0.6, 0.5, 0.2 }
};
// Replace SqlConnection with what is specific to your ADO.NET provider / DBMS.
using (var conn = new SqlConnection("your connection string")) {
conn.Open();
using (var cmd = conn.CreateCommand()) {
// Construct SQL text (use parameter prefix specific to your DBMS instead of @ as appropriate).
var sb = new StringBuilder();
for (int y = 0; y < pt.GetLength(0); ++y)
for (int x = 0; x < pt.GetLength(1); ++x)
sb.Append(
string.Format(
"INSERT INTO YOUR_TABLE (INDEX_X, INDEX_Y, VALUE) VALUES (@index_x_{0}_{1}, @index_y_{1}_{1}, @value_{0}_{1});",
x,
y
)
);
cmd.CommandText = sb.ToString();
// Bind parameters.
for (int y = 0; y < pt.GetLength(0); ++y)
for (int x = 0; x < pt.GetLength(1); ++x) {
cmd.Parameters.AddWithValue(string.Format("@index_x_{0}_{1}", x, y), x);
cmd.Parameters.AddWithValue(string.Format("@index_y_{0}_{1}", x, y), y);
cmd.Parameters.AddWithValue(string.Format("@value_{0}_{1}", x, y), pt[y, x]);
}
// Perform the actual insert.
cmd.ExecuteNonQuery();
}
}
}
}
There are more efficient, but DBMS-specific solutions, such as:
- Oracle:
- MS SQL Server:
- Etc...