ChatGPT解决这个技术问题 Extra ChatGPT

如何获取 Sqlite3 数据库上的列名列表?

我想将我的 iPhone 应用程序迁移到新的数据库版本。由于我没有保存某些版本,因此我需要检查某些列名是否存在。

Stackoverflow entry 建议进行选择

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

并解析结果。

这是常见的方式吗?备择方案?

对于 SQLite.swift 的具体情况,请参阅 this question and answer 获取列名的简单列表,或参阅 this one 了解迁移问题。

n
nevan king
PRAGMA table_info(table_name);

将为您提供所有列名的列表。


但您无法从该表中进行选择。这很烦人。我正在尝试这样的事情......但它不起作用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
只需将其放入 Android 上 SQLiteDatabase 的代码术语中,请编写 db.rawQuery("PRAGMA table_info(" + tablename + ")", null);
这也适用于 View。 PRAGMA table_info(View_Name);这将列出视图的所有列
为什么不在选择语句的末尾粘贴“limit 0”? int cols = sqlite3_column_count(stmt); fprintf(stdout, "%d 列\n", cols); for (int i=0; i
要作为查询执行,请参阅 @user1461607 中的 answerselect * from pragma_table_info('tblName') as tblInfo;
G
George Hilliard

如果您有 sqlite 数据库,请使用 sqlite3 命令行程序和以下命令:

列出数据库中的所有表:

.tables

要显示给定 tablename 的架构:

.schema tablename

虽然输出不那么“可读”(也许)这比 PRAGMA table_info(table_name); 更容易记住
@NickTomlin 不幸的是,这种方法需要使用 sqlite3 命令行程序,因为点命令不是有效的 SQL。
s
slfan

如果你这样做

.headers ON

你会得到想要的结果。


如何将标题与下面的内容对齐?
要始终打开它,请将其放入 your .sqliterc file
这应该适用于空表吗?我仍然没有看到列名
由于某些我不知道的原因,PRAGMA 方法和 .schema 方法都不适用于我。但是这个工作得很好。
.headers on.mode columns 将打开列名并对齐所有内容
B
Birdbuster

只是为了像我这样的超级菜鸟想知道人们的意思是什么

PRAGMA table_info('table_name') 

您想使用它作为您的准备语句,如下所示。这样做会选择一个看起来像这样的表,除了填充与您的表有关的值。

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

其中 id 和 name 是列的实际名称。因此,要获得该值,您需要使用以下方法选择列名:

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

这将返回当前行的列名。要全部获取它们或找到您想要的,您需要遍历所有行。最简单的方法是采用以下方式。

//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
    }
}

他们的意思是执行 sqlite3(或为您命名的任何名称)进入 sqlite CLI,然后输入该文本。无需为此编写大量代码:)
是的,正如@Xerus 所说......不需要大量代码。只需直接使用 sqlite3。此外,@birdbuster,它有助于指定您正在使用的语言和库。在我看来,它看起来像 C++(来自 sprintf 函数)。澄清一下是有帮助的,因为 OP 问题与语言无关。
O
Owen Pauling

如果您希望查询的输出包含列名并正确对齐为列,请在 sqlite3 中使用以下命令:

.headers on
.mode column

你会得到如下输出:

sqlite> .headers on
sqlite> .mode column
sqlite> select * from mytable;
id          foo         bar
----------  ----------  ----------
1           val1        val2
2           val3        val4

u
user1461607

获取此处未提及的列名列表的另一种方法是跨平台且不依赖于 sqlite3.exe shell,是从 PRAGMA_TABLE_INFO() 表值函数中进行选择。

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

您可以通过查询来检查某个列是否存在:

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

如果您不想从 sqlite_master 或 pragma table_info 解析 select sql 的结果,这就是您使用的。

请注意,此功能是实验性的,已在 SQLite 版本 3.16.0 (2017-01-02) 中添加。

参考:

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


这仅适用于本地数据库。如果您尝试使用附加的模式,它将无法正常工作。
B
Book Of Zeus

要获取列列表,您可以简单地使用:

.schema tablename

这不会显示使用 ALTER 语句添加的列。
S
S.M.Mousavi

我知道这是一个旧线程,但最近我需要它并找到了一个简洁的方法:

SELECT c.name FROM pragma_table_info('your_table_name') c;

你的意思是:where t.name = 'table';
您从我的回答中找到了简洁的方法吗? 😂
S
Sam Houston

当您运行 sqlite3 cli 时,输入:

sqlite3 -header

也会给出想要的结果


S
Sakthi Velan

.schema table_name

这将列出数据库中表的列名。

希望这会有所帮助!!!


B
BoltClock

如果您正在搜索任何特定列,则可以使用 Like 语句

前任:

SELECT * FROM sqlite_master where sql like('%LAST%')

D
Devolus

为了获取列信息,您可以使用以下代码段:

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);
}

这适用于视图、连接等——但这是什么 db 包装器?
这只是jdbc。没有包装。
jdbc 是一个包装器;)
K
Kevin
//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;
}

K
Kevin Hu

当你在桌子里时,sqlite 控制台中的 .schema 对我来说看起来像这样......

sqlite>.schema
CREATE TABLE players(
id integer primary key,
Name varchar(255),
Number INT,
Team varchar(255)

O
Om Shankar
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));
});             
}

嘿,我认为问题是关于 SQLite CLI。请添加至少一个解释。
Q
Quentin

这是一个老问题,但这里有一个替代答案,它检索 SQLite 数据库中的所有列,每列的关联表的名称:

WITH tables AS (SELECT name tableName, sql 
FROM sqlite_master WHERE type = 'table' AND tableName NOT LIKE 'sqlite_%')
SELECT fields.name, fields.type, tableName
FROM tables CROSS JOIN pragma_table_info(tables.tableName) fields

这将返回这种类型的结果:

{
    "name": "id",
    "type": "integer",
    "tableName": "examples"
}, {
    "name": "content",
    "type": "text",
    "tableName": "examples"
}

对于包含标识符和字符串内容的简单表。


g
gdm
-(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;
  }

t
taras

我知道为时已晚,但这将对其他人有所帮助。

要查找表的列名,您应该执行 select * from tbl_name,您将在 sqlite3_stmt * 中获得结果。并检查列迭代总提取列。请参考以下代码。

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

这将打印结果集的所有列名。


嘿,我认为问题是关于 SQLite CLI。您应该提及您使用的是哪种语言 - 这是纯 C 语言吗?
K
Kai - Kazuya Ito

下面的这个命令设置列名:

.header on

然后,它如下所示:

sqlite> select * from user;
id|first_name|last_name|age
1|Steve|Jobs|56
2|Bill|Gates|66
3|Mark|Zuckerberg|38

下面的这个命令会取消设置列名:

.header off

然后,它如下所示:

sqlite> select * from user;
1|Steve|Jobs|56
2|Bill|Gates|66
3|Mark|Zuckerberg|38

这些命令显示命令“.header”的详细信息:

.help .header

或者:

.help header

然后,它如下所示:

sqlite> .help .header
.headers on|off          Turn display of headers on or off

此外,下面的这个命令设置输出模式“box”:

.mode box

然后,它如下所示:

sqlite> select * from user;
┌────┬────────────┬────────────┬─────┐
│ id │ first_name │ last_name  │ age │
├────┼────────────┼────────────┼─────┤
│ 1  │ Steve      │ Jobs       │ 56  │
│ 2  │ Bill       │ Gates      │ 66  │
│ 3  │ Mark       │ Zuckerberg │ 38  │
└────┴────────────┴────────────┴─────┘

并且,下面的这个命令设置了输出模式“table”:

.mode table

然后,它如下所示:

sqlite> select * from user;
+----+------------+------------+-----+
| id | first_name | last_name  | age |
+----+------------+------------+-----+
| 1  | Steve      | Jobs       | 56  |
| 2  | Bill       | Gates      | 66  |
| 3  | Mark       | Zuckerberg | 38  |
+----+------------+------------+-----+

这些命令显示了命令“.mode”的详细信息:

.help .mode

或者:

.help mode

然后,它如下所示:

sqlite> .help .mode
.import FILE TABLE       Import data from FILE into TABLE
   Options:
     --ascii               Use \037 and \036 as column and row separators
     --csv                 Use , and \n as column and row separators
     --skip N              Skip the first N rows of input
     --schema S            Target table to be S.TABLE
     -v                    "Verbose" - increase auxiliary output
   Notes:
     *  If TABLE does not exist, it is created.  The first row of input
        determines the column names.
     *  If neither --csv or --ascii are used, the input mode is derived
        from the ".mode" output mode
     *  If FILE begins with "|" then it is a command that generates the
        input text.
.mode MODE ?OPTIONS?     Set output mode
   MODE is one of:
     ascii       Columns/rows delimited by 0x1F and 0x1E
     box         Tables using unicode box-drawing characters
     csv         Comma-separated values
     column      Output in columns.  (See .width)
     html        HTML <table> code
     insert      SQL insert statements for TABLE
     json        Results in a JSON array
     line        One value per line
     list        Values delimited by "|"
     markdown    Markdown table format
     qbox        Shorthand for "box --width 60 --quote"
     quote       Escape answers as for SQL
     table       ASCII-art table
     tabs        Tab-separated values
     tcl         TCL list elements
   OPTIONS: (for columnar modes or insert mode):
     --wrap N       Wrap output lines to no longer than N characters
     --wordwrap B   Wrap or not at word boundaries per B (on/off)
     --ww           Shorthand for "--wordwrap 1"
     --quote        Quote output text as SQL literals
     --noquote      Do not quote output text
     TABLE          The name of SQL table used for "insert" mode

A
Attila Puskás
     //Called when application is started. It works on Droidscript, it is tested
     function OnStart()
     {
     //Create a layout with objects vertically centered. 
     lay = app.CreateLayout( "linear", "VCenter,FillXY" );  

     //Create a text label and add it to layout.
     txt = app.CreateText( "", 0.9, 0.4, "multiline" )  
     lay.AddChild( txt );
     app.AddLayout(lay);

     db = app.OpenDatabase( "MyData" )  
  
     //Create a table (if it does not exist already).  
     db.ExecuteSql( "drop table if exists test_table" )
     db.ExecuteSql( "CREATE TABLE IF NOT EXISTS test_table " +  
       "(id integer primary key, data text, num integer)",[],null, OnError )  
        db.ExecuteSql( "insert into test_table values (1,'data10',100), 
        (2,'data20',200),(3,'data30',300)")
        //Get all the table rows.      
        DisplayAllRows("SELECT * FROM test_table");
        DisplayAllRows("select *, id+100 as idplus, 'hahaha' as blabla from 
        test_table order by id desc;") 
     }

//function to display all records 
function DisplayAllRows(sqlstring)  // <-- can you use for any table not need to 
                                //  know column names, just use a *
                                // example: 
{ 
//Use all rows what is in ExecuteSql  (try any, it will works fine)
db.ExecuteSql( sqlstring, [], OnResult, OnError ) 
} 
//Callback to show query results in debug.  
function OnResult( res )   
{  
var len = res.rows.length; 
var s = txt.GetText();  
// ***********************************************************************
// This is the answer how to read column names from table:
for(var ColumnNames in res.rows.item(0)) s += " [ "+ ColumnNames +" ] "; // "[" & "]" optional, i use only in this demo 
// ***********************************************************************
//app.Alert("Here is all Column names what Select from your table:\n"+s);
s+="\n";
for(var i = 0; i < len; i++ )   
{  
    var rows = res.rows.item(i) 
    for (var item in rows) 
        {
            s += "    " + rows[item] + "   ";
        }
    s+="\n\n";
} 
//app.Alert(s);
txt.SetText( s )  
}  
//Callback to show errors.  
function OnError( msg )   
{  
   app.Alert( "Error: " + msg )  
}  

这个答案太长而且过于冗长,而不是发布代码,请添加更多详细信息,说明如何以及为什么为用户提供解决方案,以便无需先解析即可阅读和理解
嗨,我只是想分享我的想法,因为我以前没有完全解决我的同样问题。有 DroidScript 的演示。够了,谢谢,或者如果你愿意,我会删除我的共享。对不起我的英语。
正如目前所写的那样,您的答案尚不清楚。请edit添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。您可以找到有关如何写出好答案的更多信息in the help center
F
Fairouz

如果您使用的是 SQLite3,则不支持 INFORMATION_SCHEMA。请改用 PRAGMA table_info。这将返回有关表的 6 行信息。要获取列名 (row2),请使用如下的 for 循环

cur.execute("PRAGMA table_info(table_name)")  # fetches the 6 rows of data
records = cur.fetchall() 
print(records)
for row in records:
    print("Columns: ", row[1])

R
Roman Halaida

我能够通过使用一个 sql 查询来检索具有相应列的表名,但列输出是逗号分隔的。我希望它可以帮助某人

SELECT tbl_name, (SELECT GROUP_CONCAT(name, ',') FROM PRAGMA_TABLE_INFO(tbl_name)) as columns FROM sqlite_schema WHERE type = 'table';

d
do-me

在 Python 中使用 sqlite3

Top answer PRAGMA table_info() 返回一个元组列表,可能不适合进一步处理,例如:

[(0, 'id', 'INTEGER', 0, None, 0),
 (1, 'name', 'TEXT', 0, None, 0),
 (2, 'age', 'INTEGER', 0, None, 0),
 (3, 'profession', 'TEXT', 0, None, 0)]

在 Python 中使用 sqlite3 时,只需在末尾添加一个列表推导即可过滤掉不需要的信息。

import sqlite3 as sq

def col_names(t_name):
    with sq.connect('file:{}.sqlite?mode=ro'.format(t_name),uri=True) as conn:
        cursor = conn.cursor()
        cursor.execute("PRAGMA table_info({}) ".format(t_name))
        data = cursor.fetchall()
        return [i[1] for i in data]

col_names("your_table_name")

结果

["id","name","age","profession"]

免责声明:请勿在生产中使用,因为此代码段可能会受到 SQL 注入的影响!


J
Jim Beem

获取表和列的列表作为视图:

CREATE VIEW Table_Columns AS
SELECT m.tbl_name AS TableView_Name, m.type AS TableView, cid+1 AS Column, p.*
FROM sqlite_master m, Pragma_Table_Info(m.tbl_name) p
WHERE m.type IN ('table', 'view') AND
   ( m.tbl_name = 'mypeople' OR m.tbl_name LIKE 'US_%')   -- filter tables
ORDER BY m.tbl_name;