i'm having problems to create a table in particular, this is my table
Create table EmpleadosCursos(Empleado constraint fk1_empleadoscursos references empleados,Curso constraint fk2_empleadoscursos references cursos,constraint pk_empleadoscursos primary key(empleado,curso),fecha date);
But it returns this error "Error: near "fecha": syntax error"
I can't find why, I tried with datetime too, but it didn't work
I believe that you need to have a name for your third column, something like below. :)
CREATE TABLE EmpleadosCursos(
Empleado constraint fk1_empleadoscursos references empleados,
Curso constraint fk2_empleadoscursos references cursos,
COLUMN_NAME constraint pk_empleadoscursos primary key(empleado,curso),
Fecha date
)
There is no date/time field type in SQLite. As described:
Each value stored in an SQLite database (or manipulated by the
database engine) has one of the following storage classes:
NULL. The value is a NULL value.
INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value.
REAL. The value is a floating point value, stored as an 8-byte IEEE floating point number.
TEXT. The value is a text string, stored using the database encoding (UTF-8, UTF-16BE or UTF-16LE).
BLOB. The value is a blob of data, stored exactly as it was input.
Either store Fecha as a text '2016-04-12 12:00:00' or numeric equivalent value, 1460419200 (epoch UTC format or seconds since 1970-01-01). And practically any general purpose language (Java, C#, Perl, Python, PHP) can convert prior to import or update.
Related
I'm learning SQL and SQLite at the moment, and from what I understand, SQLite doesn't support a datetime datatype.
However, when I run the command PRAGMA table_info(Orders); it's showing one column as being of type datetime.
I've read that In SQLite, the datatype of a value is associated with the value itself, not with its container. taken from here https://www.sqlite.org/datatype3.html
I'm trying to understand what exactly this means, which may help to explain.
Can someone help me understand what's going on here?
What you see in the column type when you execute:
PRAGMA table_info(tablename)
or:
SELECT * FROM pragma_table_info('tablename');
is the data type that was used for the definition of the column in the CREATE TABLE statement.
SQLite allows the use of anything (even nothing), as long as it is not a reserved word, as a data type.
This:
CREATE TABLE tablename (
column0 integer primary key,
column1 integer,
column2 text,
column3 real,
column4 string,
column5 something,
column6 Jack,
column7, -- no data type defined
column8 real char int -- ??,
column9 datetime
);
is a valid statement!
From all the above column definitions, SQLite will enforce type checking only for the column column0 which is defined as integer primary key.
From Datatypes In SQLite Version 3/Storage Classes and Datatypes:
Any column in an SQLite version 3 database, except an INTEGER PRIMARY
KEY column, may be used to store a value of any storage class.
When you define a column as datetime, don't expect SQLite to understand your intention and set any internal constraints so that the values you store in it will be datetime-like.
Actually, by the rules described in Determination Of Column Affinity, this column will have NUMERIC affinity.
Of course you can store datetime values in a column, as described in Date and Time Datatype, by using INTEGER, REAL or TEXT data type, depending on the form of the datetimes that you want: Unix Times, Julian day numbers or ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS") strings respectively.
In conclusion, SQLite will never complain for any value in any column defined as any data type (except for integer primary key).
It is your responsibility to make sure that you store values in the proper format that you can read/write, make calculations, compare etc.
For example, never store text datetimes in any other format than "YYYY-MM-DD HH:MM:SS.SSS" because all SQLite's datetime functions work with this format only.
To amplify #forpas's excellent answer, you can make up for SQLite's weak type-checking by using CHECK constraints in your table definitions. I frequently do that to enforce integers or string lengths, and you could use SQLite's date functions to verify that the value can be parsed as a date and lies between two values.
I am using the DBI library in R to establish a connection to an MS Access DB (in this example called "db") and then using the DBI dbGetQuery() function to pass MS Access SQL query seen below. If I run this example code segment without attempting to define format it creates a new table as expected. What I cannot determine is whether or not it is possible to define the format for a data type within the same query? If it is possible, what the syntax is for defining format within the CREATE TABLE statement.
Without attempting to format:
dbGetQuery(db, "CREATE TABLE MyTable
(
Table_ID AutoIncrement PRIMARY KEY,
Location CHAR NOT NULL,
Event_Date DATE NOT NULL,
Species_Code CHAR NOT NULL,
Length DOUBLE,
Weight DOUBLE,
Sex CHAR
)")
With attempting to format date, results in a syntax error:
dbGetQuery(db, "CREATE TABLE MyTable
(
Table_ID AutoIncrement PRIMARY KEY,
Location CHAR NOT NULL,
Event_Date DATE NOT NULL FORMAT \"yyyy/mm/dd\",
Species_Code CHAR NOT NULL,
Length DOUBLE,
Weight DOUBLE,
Sex CHAR
)")
To the best of my knowledge, the DATETIME field in Access defaults to mm/dd/yyyy format. I don't know if you can modify the format with a SQL command - you can change it using the table's design view.
When I want a field to have special date formatting, I use CHAR datatype (or Short Text, in Access parlance), then I use the FORMAT() function to format the date values to my liking whenever I insert a new date. This gives greater flexibility with dates.
So I've been learning a lot of SQL in school using MySQL , Oracle and SQL Server. So now i need to work with SQLite on a raspberry pi project. The thing I don't understand is datatypes. When you put your field to be int it can only save whole numbers right? And in SQLite it can save integers inside of a int datatype. So i have been reading about it and how SQLite saves data in these groups:
NULL. The value is a NULL value.
INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value.
REAL. The value is a floating point value, stored as an 8-byte IEEE floating point number.
TEXT. The value is a text string, stored using the database encoding (UTF-8, UTF-16BE or UTF-16LE).
BLOB. The value is a blob of data, stored exactly as it was input.
So it only makes a difference when saving data and not on input? I can't understand it.. How can I make my INT columns not accept integers? Or it isn't possible?
The SQLite dialect of SQL is a dynamically-typed language. Just like Python will let you create an array of mixed types like [None, 42, 3.14, 'Hello, world!', b'\x01\x23'], SQLite will let you store values of multiple types in the same column.
Storage classes
Conceptually, SQLite has five scalar data types, called “storage classes”:
The NULL type is used for the singleton value NULL, which is a sentinel value indicating an unknown or not-applicable value.
The INTEGER type is a 64-bit signed integer. The part about “stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value” is an implementation detail of the file format, and not something you as a programmer need to be concerned with. From the point of view of the C API and the SQL language, it's always 8 bytes.
The REAL type is a 64-bit floating-point number.
The TEXT type is a character string.
The BLOB type is a sequence of octets. SQL literals are X-prefixed strings of hex digits (e.g., X'0123456789ABCDEF').
If you're a Python 3.x programmer, you can think of:
NULL = None (of type NoneType)
INTEGER = int (but limited to 64 bits)
REAL = float
TEXT = str
BLOB = bytes
(This is actually the type mapping used by Python's standard sqlite3 module.)
If you're a C# programmer, you can think of:
NULL = null (but without the arbitrary distinction between value types and reference types)
INTEGER = long
REAL = double
TEXT = string
BLOB = byte[]
SQLite lets you store a value of any data type in any column. (Exception: If a column is declared as INTEGER PRIMARY KEY, and its table is not declared WITHOUT ROWID, then it actually is constrained to contain only integers, because it is an alias for the row ID.)
Column type affinity
Independent of the above list of “storage classes”, SQLite has the concept of type affinity which determines the preferred data type to store in a column. The affinitity of a column is determine by its declared datatype.
Only numeric (INTEGER and REAL) and TEXT values are affected by these automatic type conversions; there is never any implicit conversion to or from the NULL or BLOB storage classes.
So, if you declare a column with integer affinity (e.g., INT or INTEGER), but you insert a text string into it, then SQLite will automatically convert the value to an integer for you. But if it can't, it leaves it as a string. So, the string '42' becomes the integer 42, but the string 'xyz' stays as-is.
Real-affinity columns (REAL, FLOAT, DOUBLE) are similar, except that they attempt to convert strings into REAL values instead of INTEGER values. Numeric-affinity columns (NUMERIC, DECIMAL) convert strings to numbers, but will happily allow INTEGER and REAL values in the same column.
Text-affinity columns (CHAR, VARCHAR, TEXT, CLOB) will make the opposite conversion: All numbers (integer or real) are converted to strings.
Blob-affinity columns (BLOB or no declared data type) leave all values as-is.
No, it is wrong to say that in SQLite if you declare an INT column it will only accept integer values. In SQLite, you can store any datatype in any column. Therefore, you can declare the column AGE INTEGER and store the value 'I am pretty old', of type TEXT in that column.
This is quite different from virtually every other relational database, which requires the type of the value to match the type of the column it is stored in.
The actual value determines the type.
Similar to Excel.
You don't even have to define types for columns, e.g. -
create table t (c1,c2,c3);
https://www.sqlite.org/datatype3.html
Datatypes In SQLite
Most SQL database engines (every SQL database engine other than
SQLite, as far as we know) uses static, rigid typing. With static
typing, the datatype of a value is determined by its container - the
particular column in which the value is stored.
SQLite uses a more general dynamic type system. In SQLite, the
datatype of a value is associated with the value itself, not with its
container. The dynamic type system of SQLite is backwards compatible
with the more common static type systems of other database engines in
the sense that SQL statements that work on statically typed databases
should work the same way in SQLite. However, the dynamic typing in
SQLite allows it to do things which are not possible in traditional
rigidly typed databases.
drop table if exists t;
create table t (studentId int);
insert into t (studentId) values (1),(2),('Say what?'),(3),('Yep!');
select studentId from t;
sqlite> drop table if exists t;
sqlite> create table t (studentId int);
sqlite> insert into t (studentId) values (1),(2),('Say what?'),(3),('Yep!');
sqlite> select studentId from t;
studentId
----------
1
2
Say what?
3
Yep!
sqlite> .header on
sqlite> drop table t;
sqlite> create table t (studentId text);
sqlite> insert into t (studentId) values (1),(2),('Say what?'),(3),('Yep!');
sqlite> select studentId,studentId * 10 from t;
studentId studentId * 10
---------- --------------
1 10
2 20
Say what? 0
3 30
Yep! 0
I want to insert a time data in a table . So, what type of datatypes, I should use and how can I insert a time in a table? I used 'timestamp' in create table statement, but when I insert a time in table, it shows an error (error-code : ORA-01861). Please help me. I use ORACLE 11g.
DDL statement:
CREATE TABLE "SOM"."FLIGHTS"
( "FLNO" NUMBER(3,0) NOT NULL ENABLE,
"FROM" VARCHAR2(20 BYTE),
"TO" VARCHAR2(20 BYTE),
"DISTANCE" NUMBER(5,3),
"DEPARTS" TIMESTAMP (3),
"ARRIVES" TIMESTAMP (3),
"PRICE" NUMBER(5,2),
CONSTRAINT "FLIGHTS_PK" PRIMARY KEY ("FLNO") );
insert statement:
insert into flights
values (1, 'Bbsr', 'Calcutta', 600, timestamp '05:30', timestamp '06:50', 8000);
The message for ORA-01861 is literal does not match format string. This error means we're casting a string to another data type but the string has the wrong format.
Your insert statement features two casts of a string to a TIMESTAMP datatype using the ANSI SQL style timestamp() function. This function takes prescribed formats: YYYY-MM-DD HH24.MI.SS, YYYY-MM-DD HH24.MI.SS.FF and YYYY-MM-DD HH24.MI.SS.FF TZ.
You are getting ORA-01861 because your string does not match one of those formats: timestamp '05:30'.
In this case the solution is to change the column datatype: you do not want a timestamp, which is a specific time on a specific date. What you want is just the flight's take-off and landing times, which would be better expressed as number(4,2) or varchar2(5) which a check constraint.
Two other observations.
Your insert statement has numeric value which are too big for the specified number columns, which is easy to fix.
Your table definition uses oracle reserved words as column names, TO and FROM. The create statement succeeds only because you have wrapped everything in double quotes, so Oracle doesn't validate the names. Using reserved words like this is incredibly bad practice. Every time we refer to the columns we will need to write ...
select flno, "FROM", "TO" from flights;
... otherwise the we'll get ORA-00936 (SQLFiddle demo). The poor saps who have to use your table and maintain your code will curse you forever. Don't be that guy.
I am attempting to load a tab delimited text file which contains a column of values which happen to look exactly like a date, but aren't. It appears that the CSVREAD command scans the row, converts the text value in the column to a java.Sql.Date, and then sees that the target column is a VARCHAR and executes toString() to obtain the value...which is exactly NOT what I need. I actually need the raw unconverted text with no date processing whatsoever.
So, is there some way to turn off "helpful date-like column conversion" in the CSVREAD command?
Here's the simplest case I can make to demonstrate the undesired behavior:
CREATE TABLE x
(
name VARCHAR NOT NULL
value VARCHAR
) AS
SELECT * CSVREAD('C:\myfile.tab', null, 'UTF-8', chr(9))
;
The file contains three rows, a header and two records of values:
name\tvalue\n
x\t110313\n
y\t102911\n
Any assistance on how I can bypass the overhelpful part of CVSREAD would be greatly appreciated. Thank you.
(It seems you found this out yourself, but anyway):
For CSVREAD, all columns are strings. The CSVREAD function or the database do not try to convert values to a date, or in any other way try to detect the data type. The database only does what you ask it for, which is read the data as a string in your case.
If you do want to convert a column to a date, you need to do that explicitly, for example:
CREATE TABLE x(name VARCHAR NOT NULL, value TIMESTAMP) AS
SELECT *
FROM CSVREAD('C:\myfile.tab', null, 'UTF-8', chr(9));
If non-default parsing is needed, you could use:
CREATE TABLE x(name VARCHAR NOT NULL, value TIMESTAMP) AS
SELECT "name", parsedatetime("value", "M/d/y") as v
FROM CSVREAD('C:\myfile.tab', null, 'UTF-8', chr(9));
For people who don't have headers in there csv files the example could be like this:
CREATE TABLE x(name VARCHAR NOT NULL, value TIMESTAMP) AS
SELECT "0", parsedatetime("1", 'd-M-yyyy') as v
FROM CSVREAD('C:\myfile.tab', '0|1', 'UTF-8', '|');
Beware of the single quotes around the date format. When I tried the example from Thomas it gave me an error using H2:
Column "d-M-yyyy" not found; SQL statement:
My csv files:
firstdate|13-11-2013\n
seconddate|14-11-2013