2013-11-18 7 views
6

Использование System.Data.SQLite, я создаю таблицу с беззнаковых целых столбцов:неподписанных INT поля кажутся неправильно набран к System.Int32 по System.Data.SQLite

@"CREATE TABLE widgets (" + 
    @"id unsigned integer(10) PRIMARY KEY, " + 
    @"fkey unsigned integer(10), " + ... 

, а затем вставить значения как

INSERT INTO widgets (id, fkey, ...) VALUES (4294967295, 3456, ... 

Однако, перейдя по строкам и столбцам этой таблицы, я обнаружил, что row["id"] имеет тип System.Int32 (а не UInt32), и неудивительно, что 4294967295 интерпретируется как -1. Фактически, все неподписанные int-поля в таблице (а не только идентификатор первичного ключа неправильно введены как System.Int32)

Между тем спецификация типа SQLite говорит, что целые числа хранятся в 1, 2, 3, 4, 6 или 8 байтах в зависимости от величины значения. 4294967295 = 0xFFFFFFFF вписывается всего в четыре байта. Это также противоречит так называемой «динамической типизации» SQLite. Когда я вставляю больше 4294967295 положительных значений, тип остается System.Int32.

Это ошибка или функция?

PS1:

моя таблица содержит 1 строку с колонкой ID = 2^32-1 = 4294967295 (или больше), и я печатаю типы всех столбцов с

public void PrintDataTypes(DataTable dt) { 
    foreach (DataRow row in dt.Rows) { 
     foreach (DataColumn col in dt.Columns) 
      Console.WriteLine("name={0}, type={1}", 
           col.ToString(), 
           row[col].GetType().ToString()); 
     return; // after 1st row is done 
    } 
} 

И я неизменно получаю

name=id, type=System.Int32 
name=fkey, type=System.Int32 
...  
+0

См. Http://www.sqlite.org/datatype3.html - насколько я знаю, SQLite игнорирует ключевое слово «unsigned» и спецификатор размера. Чтобы определить, почему вы видите 'Int32', вы можете отправить код, который вы используете для чтения из таблицы. –

+0

Спасибо! Я добавил PS1 в исходное сообщение, чтобы объяснить, как я получаю System.Int32 – user2770141

+0

Ссылаясь на ссылку, которую вы предложили: класс хранения INTEGER, например, включает 6 различных целых типов данных различной длины. Это делает разницу на диске. Но как только значения INTEGER считываются с диска и в память для обработки, они преобразуются в самый общий тип данных (8-байтовое целое число со знаком). – user2770141

ответ

0

вы не собираетесь, чтобы получить целое число без знака столбца в SQLite, даже если вы указали беззнаковое в вашем SQL. Да, я лично считаю, что это вопиющий недостаток - он даже не выводит предупреждение, увидев вашу «неподписанную» спецификацию в вашем SQL. Таким образом, ваш столбец подписан на 64 бита, и ваше максимальное значение, которое вы можете сохранить, действительно составляет 2 до 63-й мощности.