有沒有辦法將DEFAULT關鍵字從IDataReader傳遞給SqlBulkCopy?
基本的將DEFAULT關鍵字傳遞給不可空列與SqlBulkCopy
INSERT INTO MyTable(NonNullableWithDefault)
VALUES (DEFAULT)
在我的應用程序相當於目標表必須與他們默認約束不爲空的列。
一些要上傳的數據具有這些列的值,有些則沒有。
對於沒有值的行(DBNull),它應該使用默認約束。
如this answer所述,SqlBulkCopy要麼根本不傳入ColumnMapping,要麼發送一個值。
替代我考慮
- 分裂的數據在不同的columnmappings(復)爲默認
- 檢查DB通過,並在DataReader的填充它們(慢)
- 創建單獨的轉儲表沒有約束(複雜,也許很慢)
我不能成爲第一個有這個問題的人。
人們在這種情況下使用什麼?
UPDATE
多少擺弄周圍我現在有一個查詢取我的整個數據庫的結構,然後通過該數據集到我的DataReader之後。
SELECT
columns.TABLE_SCHEMA schemaName
, columns.TABLE_NAME tableName
, columns.TABLE_SCHEMA + '.' + columns.TABLE_NAME fullTableName
, columns.COLUMN_NAME columnName
, columns.DATA_TYPE dataType
, ISNULL(columns.CHARACTER_MAXIMUM_LENGTH, -1) charlength
, columns.COLUMN_DEFAULT defaultValue
, columns.ORDINAL_POSITION ordinalPosition
FROM
information_schema.columns columns
默認值字符串的解析不是很漂亮,最有可能不適用於高級情況。但在我們的情況下,它涵蓋了所有的基地。
private object ParseDefault(DataRow row)
{
if(row.IsNull("defaultValue")) return null;
var value = row.Field<string>("defaultValue");
if (value == "(getdate())")
{
return DateTime.UtcNow;
}
var type = GetTypeForName(row.Field<string>("dataType"));
return ParseCell(value.Trim('(', ')'), type);
}
private static object ParseCell(string value, Type info)
{
if (value.Equals("NULL", StringComparison.OrdinalIgnoreCase))
{
return DBNull.Value;
}
int intValue;
if (info == typeof(bool) && int.TryParse(value, out intValue))
{
return intValue == 1;
}
var foo = TypeDescriptor.GetConverter(info);
return foo.ConvertFromInvariantString(value);
}
優點:
- 不可爲空的默認值解決辦法
- 清除驗證消息(例如最大長度)
- 手柄柱名的情況下的匹配
缺點
- 解析默認字符串值
- 無法解析SQL方面的默認值(如存儲過程)
感謝您的解釋。我仍然希望找到更好的方法,否則我可能不得不訴諸大量的插入:( –
@BorisCallens,我和你在一起 - 我真的很想聽到更好的方法來做到這一點! !如果你找到一個並且有時間,請在這裏發佈。 –
我的下一個想法是首先獲取所有的默認約束(請參閱https://stackoverflow.com/questions/141682/how-do-i-find-a -default-constraint-using-information-schema),並在我的IDataReader中用我自己的默認值替換NULL,但我暫時插入了多個值。 –