Modify Sqlite Table Column NOT NULL to NULL - sqlite

I am looking for something similar to this but I'm using sqlite3. I have tried:
sqlite> UPDATE JOBS SET JOB_TYPES = NULL;
But I got "constraint failed". Am I doing it the correct way?
I want to change the current "NOT NULL" to "NULL".

SQLite has almost no ALTER TABLE support.
The easiest method to change a table is to create a new table, and copy the data over:
CREATE TABLE Jobs2(..., JOB_TYPES NULL, ...);
INSERT INTO Jobs2 SELECT * FROM Jobs;
DROP TABLE Jobs;
ALTER TABLE Jobs2 RENAME TO Jobs;

Related

Modify a column to NULL - Oracle

I have a table named CUSTOMER, with few columns. One of them is Customer_ID.
Initially Customer_ID column WILL NOT accept NULL values.
I've made some changes from code level, so that Customer_ID column will accept NULL values by default.
Now my requirement is that, I need to again make this column to accept NULL values.
For this I've added executing the below query:
ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL
I'm getting the following error:
ORA-01451 error, the column already allows null entries so
therefore cannot be modified
This is because already I've made the Customer_ID column to accept NULL values.
Is there a way to check if the column will accept NULL values before executing the above query...??
You can use the column NULLABLE in USER_TAB_COLUMNS. This tells you whether the column allows nulls using a binary Y/N flag.
If you wanted to put this in a script you could do something like:
declare
l_null user_tab_columns.nullable%type;
begin
select nullable into l_null
from user_tab_columns
where table_name = 'CUSTOMER'
and column_name = 'CUSTOMER_ID';
if l_null = 'N' then
execute immediate 'ALTER TABLE Customer
MODIFY (Customer_ID nvarchar2(20) NULL)';
end if;
end;
It's best not to use dynamic SQL in order to alter tables. Do it manually and be sure to double check everything first.
Or you can just ignore the error:
declare
already_null exception;
pragma exception_init (already_null , -01451);
begin
execute immediate 'alter table <TABLE> modify(<COLUMN> null)';
exception when already_null then null;
end;
/
You might encounter this error when you have previously provided a DEFAULT ON NULL value for the NOT NULL column.
If this is the case, to make the column nullable, you must also reset its default value to NULL when you modify its nullability constraint.
eg:
DEFINE table_name = your_table_name_here
DEFINE column_name = your_column_name_here;
ALTER TABLE &table_name
MODIFY (
&column_name
DEFAULT NULL
NULL
);
I did something like this, it worked fine.
Try to execute query, if any error occurs, catch SQLException.
try {
stmt.execute("ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL");
} catch (SQLException sqe) {
Logger("Column to be modified to NULL is already NULL : " + sqe);
}
Is this correct way of doing?
To modify the constraints of an existing table
for example... add not null constraint to a column.
Then follow the given steps:
1) Select the table in which you want to modify changes.
2) Click on Actions.. ---> select column ----> add.
3) Now give the column name, datatype, size, etc. and click ok.
4) You will see that the column is added to the table.
5) Now click on Edit button lying on the left side of Actions button.
6) Then you will get various table modifying options.
7) Select the column from the list.
8) Select the particular column in which you want to give not null.
9) Select Cannot be null from column properties.
10) That's it.

SQLite Schema Information Metadata

I need to get column names and their tables in a SQLite database. What I need is a resultset with 2 columns: table_name | column_name.
In MySQL, I'm able to get this information with a SQL query on database INFORMATION_SCHEMA. However the SQLite offers table sqlite_master:
sqlite> create table students (id INTEGER, name TEXT);
sqlite> select * from sqlite_master;
table|students|students|2|CREATE TABLE students (id INTEGER, name TEXT)
which results a DDL construction query (CREATE TABLE) which is not helpful for me and I need to parse this to get relevant information.
I need to get list of tables and join them with columns or just get columns along with table name column. So PRAGMA table_info(TABLENAME) is not working for me since I don't have table name. I want to get all column metadata in the database.
Is there a better way to get that information as a result set by querying database?
You've basically named the solution in your question.
To get a list of tables (and views), query sqlite_master as in
SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;
(see the SQLite FAQ)
To get information about the columns in a specific table, use PRAGMA table_info(table-name); as explained in the SQLite PRAGMA documentation.
I don't know of any way to get tablename|columnname returned as the result of a single query. I don't believe SQLite supports this. Your best bet is probably to use the two methods together to return the information you're looking for - first get the list of tables using sqlite_master, then loop through them to get their columns using PRAGMA table_info().
Recent versions of SQLite allow you to select against PRAGMA results now, which makes this easy:
SELECT
m.name as table_name,
p.name as column_name
FROM
sqlite_master AS m
JOIN
pragma_table_info(m.name) AS p
ORDER BY
m.name,
p.cid
where p.cid holds the column order of the CREATE TABLE statement, zero-indexed.
David Garoutte answered this here, but this SQL should execute faster, and columns are ordered by the schema, not alphabetically.
Note that table_info also contains
type (the datatype, like integer or text),
notnull (1 if the column has a NOT NULL constraint)
dflt_value (NULL if no default value)
pk (1 if the column is the table's primary key, else 0)
RTFM: https://www.sqlite.org/pragma.html#pragma_table_info
There are ".tables" and ".schema [table_name]" commands which give kind of a separated version to the result you get from "select * from sqlite_master;"
There is also "pragma table_info([table_name]);" command to get a better result for parsing instead of a construction query:
sqlite> .tables
students
sqlite> .schema students
create table students(id INTEGER, name TEXT);
sqlite> pragma table_info(students);
0|id|INTEGER|0||0
1|name|TEXT|0||0
Hope, it helps to some extent...
Another useful trick is to first get all the table names from sqlite_master.
Then for each one, fire off a query "select * from t where 1 = 0". If you analyze the structure of the resulting query - depends on what language/api you're calling it from - you get a rich structure describing the columns.
In python
c = ...db.cursor()
c.execute("select * from t where 1=0");
c.fetchall();
print c.description;
Juraj
PS. I'm in the habit of using 'where 1=0' because the record limiting syntax seems to vary from db to db. Furthermore, a good database will optimize out this always-false clause.
The same effect, in SQLite, is achieved with 'limit 0'.
FYI, if you're using .Net you can use the DbConnection.GetSchema method to retrieve information that usually is in INFORMATION_SCHEMA. If you have an abstraction layer you can have the same code for all types of databases (NOTE that MySQL seems to swich the 1st 2 arguments of the restrictions array).
Try this sqlite table schema parser, I implemented the sqlite table parser for parsing the table definitions in PHP.
It returns the full definitions (unique, primary key, type, precision, not null, references, table constraints... etc)
https://github.com/maghead/sqlite-parser
The syntax follows sqlite create table statement syntax: http://www.sqlite.org/lang_createtable.html
This is an old question but because of the number of times it has been viewed we are adding to the question for the simple reason most of the answers tell you how to find the TABLE names in the SQLite Database
WHAT DO YOU DO WHEN THE TABLE NAME IS NOT IN THE DATABASE ?
This is happening to our app because we are creating TABLES programmatically
So the code below will deal with the issue when the TABLE is NOT in or created by the Database Enjoy
public void toPageTwo(View view){
if(etQuizTable.getText().toString().equals("")){
Toast.makeText(getApplicationContext(), "Enter Table Name\n\n"
+" OR"+"\n\nMake Table First", Toast.LENGTH_LONG
).show();
etQuizTable.requestFocus();
return;
}
NEW_TABLE = etQuizTable.getText().toString().trim();
db = dbHelper.getWritableDatabase();
ArrayList<String> arrTblNames = new ArrayList<>();
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE
type='table'", null);
if (c.moveToFirst()) {
while ( !c.isAfterLast() ) {
arrTblNames.add( c.getString( c.getColumnIndex("name")) );
c.moveToNext();
}
}
c.close();
db.close();
boolean matchFound = false;
for(int i=0;i<arrTblNames.size();i++) {
if(arrTblNames.get(i).equals(NEW_TABLE)) {
Intent intent = new Intent(ManageTables.this, TableCreate.class
);
startActivity( intent );
matchFound = true;
}
}
if (!matchFound) {
Toast.makeText(getApplicationContext(), "No Such Table\n\n"
+" OR"+"\n\nMake Table First", Toast.LENGTH_LONG
).show();
etQuizTable.requestFocus();
}
}

Truncate a SQLite table if it exists?

To truncate a table in SQLite I need to use this syntax:
DELETE FROM someTable
But how do I truncate the table only if it exists?
Unfortunately this throws an error:
DELETE FROM someTable IF EXISTS
This doesn't work either:
DELETE IF EXISTS FROM someTable
Thanks.
It is the two step process:
Delete all data from that table using:
Delete from TableName
Then:
DELETE FROM SQLITE_SEQUENCE WHERE name='TableName';
IMHO, it is more efficient to drop the table and re-create it. And yes, you can use "IF EXISTS" in this case.
Just do delete. This is from the SQLite documentation:
The Truncate Optimization
"When the WHERE is omitted from a DELETE statement and the table being deleted has no triggers, SQLite uses an optimization to erase the entire table content without having to visit each row of the table individually. This "truncate" optimization makes the delete run much faster. Prior to SQLite version 3.6.5, the truncate optimization also meant that the sqlite3_changes() and sqlite3_total_changes() interfaces and the count_changes pragma will not actually return the number of deleted rows. That problem has been fixed as of version 3.6.5."
I got it to work with:
SQLiteDatabase db= this.getWritableDatabase();
db.delete(TABLE_NAME, null, null);
SELECT name FROM sqlite_master where name = '<TABLE_NAME_HERE>'
If the table name does not exist then there would not be any records returned!
You can as well use
SELECT count(name) FROM sqlite_master where name = '<TABLE_NAME_HERE>'
if the count is 1, means table exists, otherwise, it would return 0
After deleting I'm also using VACUUM command. So for full TRUNCATE equivalent I use this code:
DELETE FROM <table>;
UPDATE SQLITE_SEQUENCE SET seq = 0 WHERE name = '<table>';
VACUUM;
Deleting isn't working for me for reset Auto Increment
DELETE FROM "sqlite_sequence" WHERE "name"='<table>';
To read more about VACUUM you can go here: https://blogs.gnome.org/jnelson/2015/01/06/sqlite-vacuum-and-auto_vacuum/
Unfortunately, we do not have a "TRUNCATE TABLE" command in SQLite, but you can use SQLite's DELETE command to delete the complete data from an existing table, though it is recommended to use the DROP TABLE command to drop the complete table and re-create it once again.
"sqllite" dosn't have "TRUNCATE " order like than mysql, then we have to get other way...
this function (reset_table) frist delete all data in table and then reset AUTOINCREMENT key in table....
now you can use this function every where you want...
example :
private SQLiteDatabase mydb;
private final String dbPath = "data/data/your_project_name/databases/";
private final String dbName = "your_db_name";
public void reset_table(String table_name){
open_db();
mydb.execSQL("Delete from "+table_name);
mydb.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE name='"+table_name+"';");
close_db();
}
public void open_db(){
mydb = SQLiteDatabase.openDatabase(dbPath + dbName + ".db", null, SQLiteDatabase.OPEN_READWRITE);
}
public void close_db(){
mydb.close();
}
**It is Simple, just follow 2 steps.
Step #1. Fire query "Delete from tableName", It will delete all records from table.
Step #2. There is table named "sqlite_sequence" in Sqlite Database, just browse it and you can set sequence table wise to "0" so it will start from auto id "1".**
See the screenshot attached.
there is no truncate command in sqlite.
but can be achieved by:
delete all records;
Delete from 'Table1';
then
set auto-increment to 0;
UPDATE SQLITE_SEQUENCE SET seq = 0 WHERE name = 'Table1';

Create table in SQLite only if it doesn't exist already

I want to create a table in a SQLite database only if doesn't exist already. Is there any way to do this? I don't want to drop the table if it exists, only create it if it doesn't.
From http://www.sqlite.org/lang_createtable.html:
CREATE TABLE IF NOT EXISTS some_table (id INTEGER PRIMARY KEY AUTOINCREMENT, ...);
Am going to try and add value to this very good question and to build on #BrittonKerin's question in one of the comments under #David Wolever's fantastic answer. Wanted to share here because I had the same challenge as #BrittonKerin and I got something working (i.e. just want to run a piece of code only IF the table doesn't exist).
# for completeness lets do the routine thing of connections and cursors
conn = sqlite3.connect(db_file, timeout=1000)
cursor = conn.cursor()
# get the count of tables with the name
tablename = 'KABOOM'
cursor.execute("SELECT count(name) FROM sqlite_master WHERE type='table' AND name=? ", (tablename, ))
print(cursor.fetchone()) # this SHOULD BE in a tuple containing count(name) integer.
# check if the db has existing table named KABOOM
# if the count is 1, then table exists
if cursor.fetchone()[0] ==1 :
print('Table exists. I can do my custom stuff here now.... ')
pass
else:
# then table doesn't exist.
custRET = myCustFunc(foo,bar) # replace this with your custom logic

Add not null DateTime column to SQLite without default value?

I can't add a not null constraint or remove a default constraint. I would like to add a datetime column to a table and have all the values set to anything (perhaps 1970 or year 2000) but it seems like i cant use not null without a default and I cant remove a default once added in. So how can i add this column? (once again just a plain datetime not null)
Instead of using ALTER TABLE ADD COLUMN, create a new table that has the extra column, and copy your old data. This will free you from the restrictions of ALTER TABLE and let you have a NOT NULL constraint without a default value.
ALTER TABLE YourTable RENAME TO OldTable;
CREATE TABLE YourTable (/* old cols */, NewColumn DATETIME NOT NULL);
INSERT INTO YourTable SELECT *, '2000-01-01 00:00:00' FROM OldTable;
DROP TABLE OldTable;
Edit: The official SQLite documentation for ALTER TABLE now warns against the above procedure because it “might corrupt references to that table in triggers, views, and foreign key constraints.” The safe alternative is to use a temporary name for the new table, like this:
CREATE TABLE NewTable (/* old cols */, NewColumn DATETIME NOT NULL);
INSERT INTO NewTable SELECT *, '2000-01-01 00:00:00' FROM YourTable;
DROP TABLE YourTable;
ALTER TABLE NewTable RENAME TO YourTable;

Resources