Вопрос:
У меня есть таблица базы данных, имеющая один столбец, определяемый как timestamp without time zone. Теперь из моего приложения С#, когда я пытаюсь вставить нулевое значение в этот столбец, используя NpgSql BeginBinaryImport он дает сообщение об ошибке, как указано ниже:
08P01: недостаточное количество данных, оставшихся в сообщении
Ниже приведен код, который я пытаюсь выполнить:
static void Main(string[] args) { BulkInsert(); } private static void BulkInsert() { DataTable table = new DataTable(); table.Columns.Add(«firstname», typeof(String)); table.Columns.Add(«lastname», typeof(String)); table.Columns.Add(«logdatetime», typeof(DateTime)); table.Columns.Add(«status», typeof(int)); table.Columns.Add(«id», typeof(long)); var dataRow = table.NewRow(); dataRow[«firstname»] = «MyFirstName»; dataRow[«lastname»] = «MyLastName»; dataRow[«logdatetime»] = DBNull.Value; dataRow[«status»] = 1; dataRow[«id»] = 10; table.Rows.Add(dataRow); var data = new DataAccess(); using (var npgsqlConn = new NpgsqlConnection([ConnectionString])) { npgsqlConn.Open(); var commandFormat = string.Format(CultureInfo.InvariantCulture, «COPY {0} {1} FROM STDIN BINARY», «logging.testtable», «(firstName,LastName,logdatetime,status,id)»); using (var writer = npgsqlConn.BeginBinaryImport(commandFormat)) { foreach (DataRow item in dataTable.Rows) { writer.StartRow(); foreach (var item1 in item.ItemArray) { writer.Write(item1); } } } npgsqlConn.Close(); } Лучший ответ:
Проблема заключается в том, что DBNull.Value вы пытаетесь написать – Npgsql не поддерживает запись нулей таким образом. Чтобы написать нуль, вам нужно использовать метод WriteNull().
Я могу заставить Npgsql принять DBNull.Value, но только для перегрузки Write() который также принимает NpgsqlDbType (потому что Npgsql должен написать тип данных, а с DBNull.Value мы понятия не имеем, что это такое).
EDIT: сделайте это, см. Https://github.com/npgsql/npgsql/issues/1122.
Ответ №1
Я столкнулся с такой же проблемой, в то время как массовое копирование данных в таблицу. Чтобы решить эту проблему, я создал метод расширения, поэтому вам не нужно проверять нуль во всех полях
public static void WriteWithNullCheck(this NpgsqlBinaryImporter writer, string value) { if (string.IsNullOrEmpty(value)) { writer.WriteNull(); } else { writer.Write(value); } }
это можно сделать общим
public static void WriteWithNullCheck<T>(this NpgsqlBinaryImporter writer, T value,NpgsqlDbType type) { if (value == null) { writer.WriteNull(); } else { writer.Write(value, type); } }