438

I want to migrate my iPhone app to a new database version. Since I don't have some version saved, I need to check if certain column names exist.

This Stackoverflow entry suggests doing the select

SELECT sql FROM sqlite_master
WHERE tbl_name = 'table_name' AND type = 'table'

and parse the result.

Is that the common way? Alternatives?

Pranav Totla
  • 1,172
  • 1
  • 12
  • 25
luebken
  • 4,901
  • 5
  • 20
  • 18
  • For the specific case of `SQLite.swift`, see [this question and answer](http://stackoverflow.com/questions/36784596/how-to-get-a-list-of-column-names-with-sqlite-swift) for a simple list of column names or [this one](http://stackoverflow.com/a/29866725/3681880) for migration issues. – Suragch Apr 22 '16 at 04:10
  • Possible duplicate of [How to get a list of column names](https://stackoverflow.com/questions/685206/how-to-get-a-list-of-column-names) – Owen Pauling Oct 31 '18 at 11:20

19 Answers19

660
PRAGMA table_info(table_name);

will get you a list of all the column names.

nevan king
  • 108,735
  • 42
  • 196
  • 237
  • 21
    but you can't select from that table. It's just plain annoying. I'm trying something like this... but it don't work `create temporary table TmpCols (cid integer, name text, type text, nn bit, dflt_value, pk bit); .mode insert TmpCols .output cols PRAGMA TABLE_INFO('yourtable'); .read cols .mode csv .output stdout` – Jason Jan 05 '12 at 07:03
  • Just to put this into code terms for SQLiteDatabase on Android, write `db.rawQuery("PRAGMA table_info(" + tablename + ")", null);` – Noumenon Jun 08 '13 at 14:14
  • 4
    This will also work in case of View. PRAGMA table_info(View_Name); This will list all columns of a View –  Jul 26 '13 at 03:00
  • why not just stick "limit 0" on the end of a select statement? int cols = sqlite3_column_count(stmt); fprintf(stdout, "%d columns\n", cols); for (int i=0; i – Erik Aronesty May 20 '15 at 21:09
  • @ErikAronesty limit 0 does not return any columns. – William Entriken May 31 '17 at 18:22
  • Why is it called a Pragma? Aren't those used to hack the compiler? Wtf is it doing here lol? – ytpillai Sep 01 '18 at 23:40
  • @ytpillai not to hack the compiler, but to give it instructions :) https://www.wikiwand.com/en/Directive_(programming) - it is used a bit differently in SQLite: https://www.tutorialspoint.com/sqlite/sqlite_pragma.htm – Xerus Aug 13 '20 at 08:58
  • To execute as a query, see [answer](https://stackoverflow.com/a/54962853/458354) from @user1461607: `select * from pragma_table_info('tblName') as tblInfo;` – mdisibio Sep 05 '20 at 02:03
  • @Jason you can select from the table, check my answer – user1461607 Sep 20 '20 at 02:06
  • @Xerus Fair enough, I always just thought of it as hacking the compiler because you change the flow of how it operates. But that would be similar to using kernel options meaning you are hacking the kernel which doesn't make sense. Agreed! – ytpillai Oct 09 '20 at 19:09
245

If you have the sqlite database, use the sqlite3 command line program and these commands:

To list all the tables in the database:

.tables

To show the schema for a given tablename:

.schema tablename
George Hilliard
  • 13,581
  • 5
  • 50
  • 88
  • 9
    Although the output isn't as "readable" (perhaps) this is_much_ easier to remember than `PRAGMA table_info(table_name);` – Nick Tomlin Sep 14 '14 at 21:24
  • 10
    @NickTomlin Unfortunately, this method requires having the sqlite3 command line program, as dot commands are not valid SQL. – Michael Feb 19 '15 at 17:49
227

If you do

.headers ON

you will get the desired result.

slfan
  • 8,209
  • 115
  • 61
  • 73
Roland Orre
  • 2,371
  • 1
  • 7
  • 4
125

Just for super noobs like me wondering how or what people meant by

PRAGMA table_info('table_name') 

You want to use use that as your prepare statement as shown below. Doing so selects a table that looks like this except is populated with values pertaining to your table.

cid         name        type        notnull     dflt_value  pk        
----------  ----------  ----------  ----------  ----------  ----------
0           id          integer     99                      1         
1           name                    0                       0

Where id and name are the actual names of your columns. So to get that value you need to select column name by using:

//returns the name
sqlite3_column_text(stmt, 1);
//returns the type
sqlite3_column_text(stmt, 2);

Which will return the current row's column's name. To grab them all or find the one you want you need to iterate through all the rows. Simplest way to do so would be in the manner below.

//where rc is an int variable if wondering :/
rc = sqlite3_prepare_v2(dbPointer, "pragma table_info ('your table name goes here')", -1, &stmt, NULL);

if (rc==SQLITE_OK)
{
    //will continue to go down the rows (columns in your table) till there are no more
    while(sqlite3_step(stmt) == SQLITE_ROW)
    {
        sprintf(colName, "%s", sqlite3_column_text(stmt, 1));
        //do something with colName because it contains the column's name
    }
}
Birdbuster
  • 1,299
  • 1
  • 8
  • 12
  • 1
    What they meant by that is to execute `sqlite3` (or whatever it is named for you) to go into the sqlite CLI and then type in that text. No need to write extensive code for that :) – Xerus Aug 13 '20 at 08:53
  • Yes, as @Xerus says... no need for extensive code. Just use `sqlite3` directly. Also, @birdbuster, it helps to specify the language and library you are using. It *looks* to me like C++ (from the `sprintf` function). It is helpful to clarify, since the OP question was language-agnostic. – Mike Williamson Sep 30 '20 at 14:57
72

If you want the output of your queries to include columns names and be correctly aligned as columns, use these commands in sqlite3:

.headers on
.mode column

You will get output like:

sqlite> .headers on
sqlite> .mode column
sqlite> select * from mytable;
id          foo         bar
----------  ----------  ----------
1           val1        val2
2           val3        val4
Owen Pauling
  • 9,864
  • 18
  • 50
  • 58
  • WOW!!! I didn't know about the `.mode column`. What a killer tool to quickly visualize and debug data interactively on-the-fly! Thanks!! :-) +1! – rmbianchi Jan 22 '21 at 21:26
  • This was very helpful, IMHO this should eventually get accepted! – monamona Apr 22 '21 at 05:08
38

An alternative way to get a list of column names not mentioned here is to select from a pragma function:

SELECT name FROM PRAGMA_TABLE_INFO('your_table');
name      
tbl_name  
rootpage  
sql

You can check if a certain column exists by running:

SELECT 1 FROM PRAGMA_TABLE_INFO('your_table') WHERE name='sql';
1

This is what you use if you don't want to parse the result of select sql from sqlite_master or pragma table_info.

Reference:

https://www.sqlite.org/pragma.html#pragfunc

user1461607
  • 1,730
  • 1
  • 20
  • 21
  • 1
    Nice clean approach. And I didn't know of PRAGMA functions before this. Thank you. – Faheem Mitha Jun 01 '19 at 13:37
  • Very useful snippet, I have used at once in my own code. Thanks for sharing!! :-) Also, I didn't know about `PRAGMA`; thanks for the example and the link! +1!! – rmbianchi Jan 22 '21 at 21:28
31

To get a list of columns you can simply use:

.schema tablename
Book Of Zeus
  • 48,229
  • 18
  • 169
  • 166
Aditya Joardar
  • 434
  • 4
  • 9
17

When you run the sqlite3 cli, typing in:

sqlite3 -header

will also give the desired result

Sam Houston
  • 2,357
  • 1
  • 18
  • 31
14

I know it is an old thread, but recently I needed the same and found a neat way:

SELECT c.name FROM pragma_table_info('your_table_name') c;
S.M.Mousavi
  • 4,279
  • 6
  • 37
  • 50
Slavian Petrov
  • 192
  • 1
  • 3
11

you can use Like statement if you are searching for any particular column

ex:

SELECT * FROM sqlite_master where sql like('%LAST%')
BoltClock
  • 630,065
  • 150
  • 1,295
  • 1,284
Raamalakshmanan
  • 127
  • 1
  • 2
9

.schema table_name

This will list down the column names of the table from the database.

Hope this will help!!!

Sakthi Velan
  • 165
  • 2
  • 9
6

In order to get the column information you can use the following snippet:

String sql = "select * from "+oTablename+" LIMIT 0";
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery(sql);
ResultSetMetaData mrs = rs.getMetaData();
for(int i = 1; i <= mrs.getColumnCount(); i++)
{
    Object row[] = new Object[3];
    row[0] = mrs.getColumnLabel(i);
    row[1] = mrs.getColumnTypeName(i);
    row[2] = mrs.getPrecision(i);
}
Devolus
  • 20,356
  • 11
  • 56
  • 104
6
//JUST little bit modified the answer of giuseppe  which returns array of table columns
+(NSMutableArray*)tableInfo:(NSString *)table{

    sqlite3_stmt *sqlStatement;

    NSMutableArray *result = [NSMutableArray array];

    const char *sql = [[NSString stringWithFormat:@"PRAGMA table_info('%@')",table] UTF8String];

    if(sqlite3_prepare(md.database, sql, -1, &sqlStatement, NULL) != SQLITE_OK)

    {
        NSLog(@"Problem with prepare statement tableInfo %@",
                [NSString stringWithUTF8String:(const char *)sqlite3_errmsg(md.database)]);

    }

    while (sqlite3_step(sqlStatement)==SQLITE_ROW)
    {
        [result addObject:
          [NSString stringWithUTF8String:(char*)sqlite3_column_text(sqlStatement, 1)]];
    }

    return result;
}
Kevin
  • 2,639
  • 29
  • 56
Dattatray Deokar
  • 1,334
  • 1
  • 16
  • 29
5

.schema in sqlite console when you have you're inside the table it looks something like this for me ...

sqlite>.schema
CREATE TABLE players(
id integer primary key,
Name varchar(255),
Number INT,
Team varchar(255)
Kevin Hu
  • 61
  • 1
  • 1
4
function getDetails(){
var data = [];
dBase.executeSql("PRAGMA table_info('table_name') ", [], function(rsp){
    if(rsp.rows.length > 0){
        for(var i=0; i<rsp.rows.length; i++){
            var o = {
                name: rsp.rows.item(i).name,
                type: rsp.rows.item(i).type
            } 
            data.push(o);
        }
    }
    alert(rsp.rows.item(0).name);

},function(error){
    alert(JSON.stringify(error));
});             
}
Om Shankar
  • 205
  • 2
  • 10
  • Hey, I think the question was about the SQLite CLI. Please, add least add an explanation. – Xerus Aug 13 '20 at 08:50
3
-(NSMutableDictionary*)tableInfo:(NSString *)table
{
  sqlite3_stmt *sqlStatement;
  NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
  const char *sql = [[NSString stringWithFormat:@"pragma table_info('%s')",[table UTF8String]] UTF8String];
  if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
  {
    NSLog(@"Problem with prepare statement tableInfo %@",[NSString stringWithUTF8String:(const char *)sqlite3_errmsg(db)]);

  }
  while (sqlite3_step(sqlStatement)==SQLITE_ROW)
  {
    [result setObject:@"" forKey:[NSString stringWithUTF8String:(char*)sqlite3_column_text(sqlStatement, 1)]];

  }

  return result;
  }
gdm
  • 7,022
  • 3
  • 33
  • 59
3

I know it's too late but this will help other.

To find the column name of the table, you should execute select * from tbl_name and you will get the result in sqlite3_stmt *. and check the column iterate over the total fetched column. Please refer following code for the same.

// sqlite3_stmt *statement ;
int totalColumn = sqlite3_column_count(statement);
for (int iterator = 0; iterator<totalColumn; iterator++) {
   NSLog(@"%s", sqlite3_column_name(statement, iterator));
}

This will print all the column names of the result set.

taras
  • 5,216
  • 9
  • 32
  • 41
Rohit Kale
  • 1,262
  • 11
  • 31
  • Hey, I think the question was about the SQLite CLI. You should mention which language you are using - is this plain C? – Xerus Aug 13 '20 at 08:51
1

If all else fails, you can always submit a query, limiting the return rows to none:

select * from MYTABLENAME limit 0
user2589273
  • 1,866
  • 16
  • 23
0

Maybe you just want to print the table headers on the console. This is my code: (for each table)

    // ------------------ show header ----------------


    char sqlite_stmt_showHeader[1000];
    snprintf(sqlite_stmt_showHeader, 1000, "%s%s", "SELECT * FROM ", TABLE_NAME_STRING UTF8String]);

    sqlite3_stmt* statement_showHeader;
    sqlite3_prepare_v2(DATABASE, sqlite_stmt_showHeader, -1, &statement_showHeader, NULL);

    int headerColumnSize = sqlite3_column_count(statement_showHeader);

    NSString* headerRow = @"|";

    for (int j = 0; j < headerColumnSize; j++) {
        NSString* headerColumnContent = [[NSString alloc] initWithUTF8String:(const char*)sqlite3_column_name(statement_showHeader, j)];
        headerRow = [[NSString alloc] initWithFormat:@"%@ %@ |", headerRow, headerColumnContent];
    }

    NSLog(@"%@", headerRow);


    sqlite3_finalize(statement_showHeader);

    // ---------------- show header end ---------------------
Neo Wang
  • 26
  • 3
  • Hey, I think the question was about the SQLite CLI. Please, add least add an explanation. – Xerus Aug 13 '20 at 08:51