Home > Back-end >  Data types and data type affinity in SQLite?
Data types and data type affinity in SQLite?

Time:02-16

The SQLite3 documentation on data types makes it clear that SQLite does not enforce column data types. Rather a data type "affinity" is defined which is the recommended data type for the column. The recommendation is not a requirement as in other database systems, and the column can store data in any type.

Am looking for a programmatic way to access the affinity for a column (i.e. what SQLite interpreted as the data type hint from the CREATE TABLE statement).

Sample C# code using the wrapper System.Data.SQLite.dll in Visual Studio 2019 on this table:

-- SQL CREATE TABLE
CREATE TABLE "MyTable" (
    "txt_Text"  TEXT,
    "txt_Text20"    TEXT(20),
    "txt_Memo"  MEMO,
    "num_Int"   INTEGER,
    "num_Bit"   BIT,
    "num_Bool"  BOOLEAN,
    "num_Byte"  BYTE,
    "float_Single"  FLOAT,
    "float_Double"  DOUBLE,
    "float_Decimal" DECIMAL,
    "float_Currency"    CURRENCY,
    "date_Date" DATE,
    "date_DateTime" DATETIME,
    "random"    fronk
)

// C# sample code
string[] columnRestrictions = new string[4];
columnRestrictions[2] = "MyTable";
DataTable schemaColumns =
    ((DbConnection)connection).GetSchema("Columns", columnRestrictions);
if (schemaColumns.Rows.Count > 0)
{
    string typeNameSQLite;
    string typeNameEntity;
    foreach (DataRow row in schemaColumns.Rows)
    {
        typeNameSQLite = (string)row["DATA_TYPE"];
        typeNameEntity = (string)row["EDM_TYPE"];
        // These would be saved in a List<string>...
    }
}

// Results
COLUMN NAME         CREATE      ASSUMED AFFINITY(1)     DATA_TYPE(2)    EDM_TYPE(2)
txt_Text            TEXT        TEXT                    text            nvarchar
txt_Text20          TEXT(20)    TEXT                    text            nvarchar
txt_Memo            MEMO        NUMERIC                 memo            nvarchar
num_Int             INTEGER     INTEGER                 integer         integer
num_Bit             BIT         NUMERIC                 bit             bit
num_Bool            BOOLEAN     NUMERIC                 boolean         bit
num_Byte            BYTE        NUMERIC                 byte            (blank)
float_Single        FLOAT       REAL                    float           real
float_Double        DOUBLE      REAL                    double          real
float_Decimal       DECIMAL     NUMERIC                 decimal         decimal
float_Currency      CURRENCY    NUMERIC                 currency        decimal
date_Date           DATE        NUMERIC                 date            datetime
date_DateTime       DATETIME    NUMERIC                 datetime        datetime
random              fronk       NUMERIC                 fronk           (blank)

Notes:
(1) Assumed affinity derived from [the SQLite3 documentation][2]
(2) "DATA_TYPE" and "EDM_TYPE" values taken directly from the "Columns" schema

The examples given in the SQLite documentation do not mention the "MEMO" or "BIT" types, though they appear to have been processed. Also, why is the type fronk understood at all?

How do you reliably access data types and the internal storage class affinity in SQLite using code?

UPDATE

@DinoCoderSaurus provided a useful comment: Run the query SELECT typeof(field_name) FROM table_name; and process the rows. This shows the storage class SQLite used to actually save the data. For example:

 ----------------- 
| typeof(num_Int) |
 ----------------- 
| null            |
| integer         |
 ----------------- 

This is helpful, but is the answer to a different question. I'm trying to confirm what internal data type affinity SQLite determined for the column from the TABLE CREATE statement (e.g. before any data is put into the table).

CodePudding user response:

By following the rules described in Determination Of Column Affinity, I created a query that returns the affinities of all columns in a table:

SELECT cid, name, type,
       CASE
         WHEN type LIKE '%INT%' THEN 'INTEGER'
         WHEN (type LIKE '%CHAR%') OR (type LIKE '%CLOB%') OR (type LIKE '%TEXT%') THEN 'TEXT'
         WHEN (type LIKE '%BLOB%') OR (type = '') THEN 'BLOB'
         WHEN (type LIKE '%REAL%') OR (type LIKE '%FLOA%') OR (type LIKE '%DOUB%') THEN 'REAL' 
         ELSE 'NUMERIC'
       END affinity
FROM pragma_table_info('MyTable');

See the demo.

You can use it as it is, or apply its logic with the use of a programming language of your choice.

CodePudding user response:

Column affinity is available through the SQLite C API. Look for sqlite3_column_decltype and sqlite3_column_type, which return one of:

  • SQLITE_INTEGER
  • SQLITE_FLOAT
  • SQLITE_TEXT
  • SQLITE_BLOB
  • SQLITE_NULL

This is currently only available through the C/C API and not exposed in the System.Data.SQLite.dll .NET wrapper.

Affinity is not the actual storage class of saved values in SQLite. To determine the actual storage class that SQLite applied, use the typeof operator as suggested by @DinoCoderSaurus (with an example in the question).

  • Related