diff options
author | Craig Morris <cmorris98@me.com> | 2013-10-11 23:54:49 +0400 |
---|---|---|
committer | Craig Morris <cmorris98@me.com> | 2013-11-27 22:11:11 +0400 |
commit | e5a83e68577ad5beb97028c7eead0d5846f42e7c (patch) | |
tree | e62f6bd4f63a7a42001dc8ff6f484e8ca153f113 /mcs/class/System.Data | |
parent | 24169a083ec528478244880c5b11550bb4197657 (diff) |
SqlBulkCopy Implementation
This are the code changes to get the SqlBulkCopy procedure working on
mono.
Diffstat (limited to 'mcs/class/System.Data')
-rw-r--r-- | mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs | 145 |
1 files changed, 98 insertions, 47 deletions
diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs index 936e7d9ee8a..110ac095b5c 100644 --- a/mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs +++ b/mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs @@ -239,6 +239,18 @@ namespace System.Data.SqlClient { if ((int)row ["ColumnSize"] != -1) { param.Size = (int) row ["ColumnSize"]; } + + short numericPresision = (short)row ["NumericPrecision"]; + if (numericPresision != 255) { + param.Precision = (byte) numericPresision; + } + + short numericScale = (short)row ["NumericScale"]; + if (numericScale != 255) { + param.Scale = (byte) numericScale; + } + + param.IsNullable = (bool)row ["AllowDBNull"]; tmpCmd.Parameters.Add (param); break; } @@ -247,6 +259,7 @@ namespace System.Data.SqlClient { flag = false; bool insertSt = false; foreach (DataRow row in colMetaData.Rows) { + SqlDbType sqlType = (SqlDbType) row ["ProviderType"]; if (_columnMappingCollection.Count > 0) { i = 0; insertSt = false; @@ -278,21 +291,32 @@ namespace System.Data.SqlClient { if ((bool)row ["IsReadOnly"]) { continue; } + + int columnSize = (int)row ["ColumnSize"]; string columnInfo = ""; - if ((int)row ["ColumnSize"] != -1) { + + if (columnSize >= TdsMetaParameter.maxVarCharCharacters && sqlType == SqlDbType.Text) + columnInfo = "VarChar(max)"; + else if (columnSize >= TdsMetaParameter.maxNVarCharCharacters && sqlType == SqlDbType.NText) + columnInfo = "NVarChar(max)"; + else if (IsTextType(sqlType) && columnSize != -1) { columnInfo = string.Format ("{0}({1})", - (SqlDbType) row ["ProviderType"], - row ["ColumnSize"]); + sqlType, + columnSize.ToString()); } else { - columnInfo = string.Format ("{0}", (SqlDbType) row ["ProviderType"]); + columnInfo = string.Format ("{0}", sqlType); } + + if ( sqlType == SqlDbType.Decimal) + columnInfo += String.Format("({0},{1})", row ["NumericPrecision"], row ["NumericScale"]); + if (flag) statement += ", "; string columnName = (string) row ["ColumnName"]; statement += string.Format ("[{0}] {1}", columnName, columnInfo); if (flag == false) flag = true; - if (tableCollations != null) { + if (IsTextType(sqlType) && tableCollations != null) { foreach (DataRow collationRow in tableCollations.Rows) { if ((string)collationRow ["name"] == columnName) { statement += string.Format (" COLLATE {0}", collationRow ["collation"]); @@ -306,41 +330,48 @@ namespace System.Data.SqlClient { private void ValidateColumnMapping (DataTable table, DataTable tableCollations) { - foreach (SqlBulkCopyColumnMapping _columnMapping in _columnMappingCollection) { - if (ordinalMapping == false && - (_columnMapping.DestinationColumn == String.Empty || - _columnMapping.SourceColumn == String.Empty)) - throw new InvalidOperationException ("Mappings must be either all null or ordinal"); - if (ordinalMapping && - (_columnMapping.DestinationOrdinal == -1 || - _columnMapping.SourceOrdinal == -1)) - throw new InvalidOperationException ("Mappings must be either all null or ordinal"); - bool flag = false; - if (ordinalMapping == false) { - foreach (DataRow row in tableCollations.Rows) { - if ((string)row ["name"] == _columnMapping.DestinationColumn) { - flag = true; - break; - } - } - if (flag == false) - throw new InvalidOperationException ("ColumnMapping does not match"); - flag = false; - foreach (DataColumn col in table.Columns) { - if (col.ColumnName == _columnMapping.SourceColumn) { - flag = true; - break; - } - } - if (flag == false) - throw new InvalidOperationException ("ColumnName " + - _columnMapping.SourceColumn + - " does not match"); - } else { - if (_columnMapping.DestinationOrdinal >= tableCollations.Rows.Count) - throw new InvalidOperationException ("ColumnMapping does not match"); - } - } + // So the problem here is that temp tables will not have any table collations. This prevents + // us from bulk inserting into temp tables. So for now we will skip the validation and + // let SqlServer tell us there is an issue rather than trying to do it here. + // So for now we will simply return and do nothing. + // TODO: At some point we should remove this function if we all agree its the right thing to do + return; + +// foreach (SqlBulkCopyColumnMapping _columnMapping in _columnMappingCollection) { +// if (ordinalMapping == false && +// (_columnMapping.DestinationColumn == String.Empty || +// _columnMapping.SourceColumn == String.Empty)) +// throw new InvalidOperationException ("Mappings must be either all null or ordinal"); +// if (ordinalMapping && +// (_columnMapping.DestinationOrdinal == -1 || +// _columnMapping.SourceOrdinal == -1)) +// throw new InvalidOperationException ("Mappings must be either all null or ordinal"); +// bool flag = false; +// if (ordinalMapping == false) { +// foreach (DataRow row in tableCollations.Rows) { +// if ((string)row ["name"] == _columnMapping.DestinationColumn) { +// flag = true; +// break; +// } +// } +// if (flag == false) +// throw new InvalidOperationException ("ColumnMapping does not match"); +// flag = false; +// foreach (DataColumn col in table.Columns) { +// if (col.ColumnName == _columnMapping.SourceColumn) { +// flag = true; +// break; +// } +// } +// if (flag == false) +// throw new InvalidOperationException ("ColumnName " + +// _columnMapping.SourceColumn + +// " does not match"); +// } else { +// if (_columnMapping.DestinationOrdinal >= tableCollations.Rows.Count) +// throw new InvalidOperationException ("ColumnMapping does not match"); +// } +// } } private void BulkCopyToServer (DataTable table, DataRowState state) @@ -411,7 +442,7 @@ namespace System.Data.SqlClient { statement += ")"; } #endregion Check requested options and add corresponding modifiers to the statement - + blkCopy.SendColumnMetaData (statement); } blkCopy.BulkCopyStart (tmpCmd.Parameters.MetaParameters); @@ -439,11 +470,14 @@ namespace System.Data.SqlClient { rowToCopy = parameter.Value = parameter.ConvertToFrameworkType (rowToCopy); } string colType = string.Format ("{0}", parameter.MetaParameter.TypeName); - if (colType == "nvarchar") { - if (row [i] != null) { + if (colType == "nvarchar" || colType == "ntext" || colType == "nchar") { + if (row [i] != null && row [i] != DBNull.Value) { size = ((string) parameter.Value).Length; size <<= 1; } + } else if (colType == "varchar" || colType == "text" || colType == "char") { + if (row [i] != null && row [i] != DBNull.Value) + size = ((string) parameter.Value).Length; } else { size = parameter.Size; } @@ -461,11 +495,14 @@ namespace System.Data.SqlClient { rowToCopy = parameter.Value = parameter.ConvertToFrameworkType (rowToCopy); } string colType = string.Format ("{0}", parameter.MetaParameter.TypeName); - if (colType == "nvarchar") { - if (row [mapping.SourceColumn] != null) { + if (colType == "nvarchar" || colType == "ntext" || colType == "nchar") { + if (row [mapping.SourceColumn] != null && row [mapping.SourceColumn] != DBNull.Value) { size = ((string) rowToCopy).Length; size <<= 1; } + } else if (colType == "varchar" || colType == "text" || colType == "char") { + if (row [mapping.SourceColumn] != null && row [mapping.SourceColumn] != DBNull.Value) + size = ((string) rowToCopy).Length; } else { size = parameter.Size; } @@ -481,16 +518,20 @@ namespace System.Data.SqlClient { If column type is SqlDbType.NVarChar the size of parameter is multiplied by 2 FIXME: Need to check for other types */ - if (colType == "nvarchar") { + if (colType == "nvarchar" || colType == "ntext" || colType == "nchar") { size = ((string) row [param.ParameterName]).Length; size <<= 1; + } else if (colType == "varchar" || colType == "text" || colType == "char") { + size = ((string) row [param.ParameterName]).Length; } else { size = param.Size; } } if (rowToCopy == null) continue; - blkCopy.BulkCopyData (rowToCopy, size, isNewRow); + + blkCopy.BulkCopyData (rowToCopy, isNewRow, size, param.MetaParameter); + if (isNewRow) isNewRow = false; } // foreach (SqlParameter) @@ -505,6 +546,16 @@ namespace System.Data.SqlClient { blkCopy.BulkCopyEnd (); } + private bool IsTextType(SqlDbType sqlType) + { + return (sqlType == SqlDbType.NText || + sqlType == SqlDbType.NVarChar || + sqlType == SqlDbType.Text || + sqlType == SqlDbType.VarChar || + sqlType == SqlDbType.Char || + sqlType == SqlDbType.NChar); + } + public void WriteToServer (DataRow [] rows) { if (rows == null) |