sqlite tables don't need column names? - sqlite

In sqlite I was able to create a table with the following command:
create table myTable(varchar, date, int);
Notice that there are no column names! I discovered this when I used column names, and when I executed a where statement, it didn't work with the column name, but it worked when I specified the variable type instead. What's up with that?

But they became names instead of datatypes:
sqlite> create table myTable(varchar, date, int);
sqlite> .headers on
sqlite> insert into myTable Values(1,1,1);
sqlite> select * from myTable;
varchar|date|int
1|1|1

Related

Is there a way that i can select my rows without a the header row in sqlite? [duplicate]

What happens when you turn the header on/off in sqlite? What does the header correspond to? What does it mean?
If you mean the following in sqlite3 command-line client...
.headers on|off Turn display of headers on or off
... enabling the feature outputs column names in a header row before printing out query results. Example:
sqlite> create table foo(bar,baz);
sqlite> insert into foo values(1,2);
sqlite> select * from foo;
1|2
sqlite> .headers on
sqlite> select * from foo;
bar|baz
1|2

how to set primary key in csv imported by sqlite

I have the following table stored as a csv file:
project_number,project_name
1,project_1
2,project_2
3,project_3
I figured out how to import this and show its schema in an sqlite3 database as follows:
sqlite> .mode csv
sqlite> .import
sqlite> .import test.csv test
sqlite> .schema test
CREATE TABLE test(
"project_number" TEXT,
"project_name" TEXT
);
I would like to now set the column project_number as my primary key and also set it to be an integer. I understand from previous questions that this is difficult to do by altering the original table, so I tried to create a new table an populated using a combination of create table, create table as, insert into and select * from as indicated here
sqlite> create table test_2 (project_name text, project_number primary key);
sqlite> insert into test_2 (select project_name, project_number from test);
Error: near "select": syntax error
But as you can see this caused a syntax error and I don't understand why. How do I set the primary key for tables imported from csvs?
You can also create the table first and then import data into it. Assuming a Linux or Unix environment:
sqlite> create table test(project_number integer primary key, project_name text);
sqlite> .mode csv
sqlite> .import '| tail -n +2 test.csv' test
will skip the first header row in the file and insert the rest.
Try this:
insert into test_2 (project_number, project_name)
select project_number, project_name from test;
I guess insert into example at https://dba.stackexchange.com/a/41108/26454 is wrong: one need to list columns after table name, reference.

sqlite column constraint not in set of values

In sqlite, how do I restrict the values of a column to being not in another table/view column?
For example
sqlite> create table tab1(col1 check (col1 not in (1,2)));
does what I want except that it seems only to exclude hard-coded values. However, the following does not work -
sqlite> create table tab2(vals_to_exclude);
sqlite> insert into tab2 values(1);
sqlite> insert into tab2 values(2);
sqlite> create table tab3(col1 check (col1 not in (select vals_to_exclude from tab2)));
Error: subqueries prohibited in CHECK constraints
Is it possible to constrain a column to exclude a dynamically determined set of values?
If the built-in mechanisms are not sufficient, implement the check manually with a trigger:
CREATE TRIGGER tab3_col1_not_in_tab2
BEFORE INSERT ON tab3 -- you also need a trigger for UPDATEs
FOR EACH ROW
WHEN EXISTS (SELECT 1
FROM tab2
WHERE vals_to_exclude = NEW.col1)
BEGIN
SELECT RAISE(FAIL, "col1 conflicts with tab2");
END;
or, alternatively:
CREATE TRIGGER tab3_col1_not_in_tab2
BEFORE INSERT ON tab3 -- you also need a trigger for UPDATEs
FOR EACH ROW
BEGIN
SELECT RAISE(FAIL, "col1 conflicts with tab2")
FROM tab2
WHERE vals_to_exclude = NEW.col1;
END;

ALTER COLUMN in sqlite

How do I alter column in sqlite?
This is in Postgresql
ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;
I believe there is no ALTER COLUMN in sqlite at all, only ALTER TABLE is supported.
Any idea? Thanks!
There's no ALTER COLUMN in sqlite.
I believe your only option is to:
Rename the table to a temporary name
Create a new table without the NOT NULL constraint
Copy the content of the old table to the new one
Remove the old table
This other Stackoverflow answer explains the process in details
While it is true that the is no ALTER COLUMN, if you only want to rename the column, drop the NOT NULL constraint, or change the data type, you can use the following set of dangerous commands:
PRAGMA writable_schema = 1;
UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';
PRAGMA writable_schema = 0;
You will need to either close and reopen your connection or vacuum the database to reload the changes into the schema.
For example:
Y:\> **sqlite3 booktest**
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> **create table BOOKS ( title TEXT NOT NULL, publication_date TEXT NOT
NULL);**
sqlite> **insert into BOOKS VALUES ("NULLTEST",null);**
Error: BOOKS.publication_date may not be NULL
sqlite> **PRAGMA writable_schema = 1;**
sqlite> **UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT
NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';**
sqlite> **PRAGMA writable_schema = 0;**
sqlite> **.q**
Y:\> **sqlite3 booktest**
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> **insert into BOOKS VALUES ("NULLTEST",null);**
sqlite> **.q**
REFERENCES FOLLOW:
pragma writable_schema
When this pragma is on, the SQLITE_MASTER tables in which database can be changed using ordinary UPDATE, INSERT, and DELETE statements. Warning: misuse of this pragma can easily result in a corrupt database file.
[alter table](From http://www.sqlite.org/lang_altertable.html)
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table. It is not possible to rename a column, remove a column, or add or remove constraints from a table.
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table. It is not possible to rename a column, remove a column, or add or remove constraints from a table. But you can alter table column datatype or other property by the following steps.
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT
For more detail you can refer the link.
CREATE TABLE temp_Table(x,y[,etc]);
INSERT INTO temp_Table SELECT * FROM Table;
DROP TABLE Table;
ALTER TABLE temp_Table RENAME TO Table;
Thanks for helping me to find a definitive method!
ALTER COLUMN does not exist in SQLite.
Only Supported alter operations:
Alter Table Name
Alter Table Column Name
Add New Column
Drop Column
Alex Jasmin's answer shows possible way
Reference:
Sqlite Alter Table

sqlite SELECT returns all records when querying a column for a value with the same name as the column

$ sqlite3 test.db
SQLite version 3.6.21
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> CREATE TABLE test(foo text);
sqlite> INSERT INTO test VALUES ("foo");
sqlite> INSERT INTO test VALUES ("bar");
sqlite> SELECT * FROM test WHERE foo="foo";
foo
bar
sqlite>
It seems that the query treats "foo" as a reference to the name of the column, rather than as a string constant. How do I get this query to only return foo, not bar? Are there options besides renaming the column?
Sqlite3 Keywords
sqlite> SELECT * FROM test WHERE foo='foo';
use single quotes.

Resources