The Difference between SQLite NVARCHAR and NVARCHAR2 - sqlite

I don't know what is the difference between SQLite NVARCHAR and NVARCHAR2 column.
I know that NVARCHAR is a Unicode-only text column, but what about NVARCHAR2?

There is a difference. In a way...
HereĀ“s the thing:
As Lasse V. Karlsen says, SQLite does not act on the types you mentioned nor does it restrict the length by an argument passed in like in NVARCHAR(24) (but you could do check constraints to restrict length).
So why are these available in SQLite Expert (and other tools)?
This info will be saved in the database schema (please check https://www.sqlite.org/datatype3.html#affinity and http://www.sqlite.org/pragma.html#pragma_table_info) So should you bother to set these when creating a SQLite db as it will not be used by SQLite?
Yes if you will be using any tool to generate code from the schema! Maybe somebody will ask you to transfer the db to MSSQL, then there are some great tools that will use the schema and will map your SQLite to MSSQL in a blink. Or maybe you will use some .NET tool to map the tables into POCO classes, and these can also use the schema to map to the correct type and they will also use the restrictions and transfer these into data annotations on the properties that the columns map to. And EntityFramework 7 will have support built in for SQLite and their code generation will surely make use of the schema.

There is no difference.
SQLite does not operate with strict data types like that, it has "storage classes".
If you check the official documentation you'll find this rule, one of five used to determine which storage class to assign to a column from the data type you specify:
If the declared type of the column contains any of the strings "CHAR", "CLOB", or "TEXT" then that column has TEXT affinity. Notice that the type VARCHAR contains the string "CHAR" and is thus assigned TEXT affinity.
There are 5 rules in total but rule 2 covers NVARCHAR and NVARCHAR2 and both will assign the storage class TEXT to the column.

Related

How can I configure a String column to use 'char' as the unit of size instead of 'byte' in DataNucleus

I'm using DataNucleus as my persistence layer (JDO) and am forced to use Oracle 11g as a database (using 11g XE for development). Unfortunately since version 11.2 the default length semantics (NLS_LENGTH_SEMANTICS) for VARCHAR columns have been set to byte instead of char which means that all columns that only provide a size will result in a type definition like this:
VARCHAR2(50 byte)
instead of:
VARCHAR2(50 char)
From Oracle's perspective the solution is threefold:
declare a unit in your size definiton (what I'm trying to achieve with JDO metadata)
alter the NLS_LENGTH_SEMANTICS attribute on every session
alter the NLS_LENGTH_SEMANTICS attribute globally (which seems not to work with the "Express Edition", I've already wasted a whole day on this)
I've searched the Mapping and Persistence Documention up and down to find metadata attributes that let me do this. I can specify jdbcType, sqlType and of course length for a column. But no unit.
Any help would be greatly appreciated.

How to use SQLite 3 type affinity?

According to SQLite 3 documentation says it has "type affinity" feature to enforce column data types. But how to turn it on?
Type affinity does not force column data types - it simply makes a suggestion as to how the underlying storage engine stores the data.
Under the "type affinity" section:
The type affinity of a column is the recommended type for data stored
in that column. The important idea here is that the type is
recommended, not required. Any column can still store any type of data.
(emphasis added)
As far as "how to turn it on," there's no such thing. This is how SQLite works all the time. There's nothing to turn on or off in order to get this functionality.
The column data types are not enforced, just suggested by their declared types in the create table statement. This is what they mean by type affinity.
The type affinity of a column is the recommended type for data stored in that column. The important idea here is that the type is recommended, not required. Any column can still store any type of data. It is just that some columns, given the choice, will prefer to use one storage class over another. The preferred storage class for a column is called its "affinity".

How to create a primary key as A1/D-M/100000 in SQL Server 2005?

How to create a primary key as A1/D-M/100000 in SQL Server 2005 in Visual Studio 2008 ?
Use varchar(20) as column type and generate the primary key value from the code.
Your request is not possible in SQL Server as requested, which makes me want to tell you to do some more reading.
However, you can achieve something similar by creating a primary key in Visual Basic, and storing that value in a char or varchar field in SQL, as suggested by Adrian Godong's answer.
That said, what I would do if this were my database, is create a normal PK using int or bigint (depending on how many rows I'm planning to store), and using a second column as char or varchar, with an appropriate index, to store the Ax/D-M/xxxxxx values.
What you are wanting to do is mix business rules with SQL Server's database rules, and that's a very bad idea. SQL does not care what your data looks like, so you should not force it to do so. Your business rules may change down the line, and this would be much easier to accommodate if you do a proper PK to start with, that does not rely on some arbitrary naming convention.
What parts of that key are fixed, which change from row to row??
E.g. where does the "A1" or the "D-M" come from? Are they the same for all rows? Do they change from row to row??
If those parts are fixed, and only the big number in the middle needs to change, you could:
define a column of type ID INT IDENTITY(100000,1) for the number
define a computed column like this:
ALTER TABLE dbo.YourTable
ADD YourPKField AS 'A1/D-M/' + CAST(ID AS VARCHAR(6)) PERSISTED
In that way, SQL Server would auto-increment your ID field, and YourPKField would contain the values:
A1/D-M/100000
A1/D-M/100001
A1/D-M/100002
A1/D-M/100003
....
and so on - automatically, without you doing anything more.
Use an INT IDENTITY(100000,1) as your Primary key.
Add the calculated (displayed) key wherever you need it (queries...). It's decoration, and as such, it's part of the front-end, not of your data.

Declaring data types in SQLite

I'm familiar with how type affinity works in SQLite: You can declare column types as anything you want, and all that matters is whether the type name contains "INT", "CHAR", "FLOA", etc. But is there a commonly-used convention on what type names to use?
For example, if you have an integer column, is it better to distinguish between TINYINT, SMALLINT, MEDIUMINT, and BIGINT, or just declare everything as INTEGER?
So far, I've been using the following:
INTEGER
REAL
CHAR(n) -- for strings with a known fixed with
VARCHAR(n) -- for strings with a known maximum width
TEXT -- for all other strings
BLOB
BOOLEAN
DATE -- string in "YYYY-MM-DD" format
TIME -- string in "HH:MM:SS" format
TIMESTAMP -- string in "YYYY-MM-DD HH:MM:SS" format
(Note that the last three are contrary to the type affinity.)
I would recommend not using self-defined types. I have observed in version 3.5.6 that types not already defined could sometimes cause an INSERT command to be refused. Maybe 1 out of 1000. I don't know if this was addressed since.
In any case, there is no sizing advantage in typing a column TINYINT or SMALLINT. The only advantage would be outside SQLite, for either parsing your column types with another program or to satisfy your personal need for tidiness. So I strongly recommend using the base types defined by SQLite and sticking to those.
Since SQLite is typeless, use whatever types make it easier for you to see what the schema looks like. Or you can match the types to your codebase.
I'm going to go with Kevin on this one. In short, knock yourself out. Make up brand new areas of mathematics if it suits your schema. Use the classnames of your ORM. Or name every type (except the PRIMARY KEY INTEGER ones) for ex-girlfriends. In the end SQLite is more about how you access and use the data.

SQLIite - how to add special data?

I is there a way to add "additional info" to a sqlite database. Something like date of creation of a database, amount of entries or name of user who created it. If I don't want to create special tables in order to store all this info especially if there will only be one of each type.
Thank you in advance.
Why not use one special table and store each special value as a name-value pair?
CREATE TABLE SpecialInfoKeyValues (
Key VARCHAR UNIQUE COLLATE NOCASE,
Value
);
Since SQLite uses "manifest typing," you can store any kind of value you want in there.
In short, no. SQLite has no concept of users, and doesn't store creation metadata.
No, there is no way to do that, you will have to use a "special" table to carry data within the file, or you will have to use external means.
There are, however, two version counters stored within the database itself: the schema_version and the user_version (see Pragmas to query/modify version values for details.) Perhaps you could abuse those. Please keep in mind, though, that by default the sqlite3 shell application does not store those when you use the .dump command to dump the database into a textual representation.

Resources