6

I have been struggling to get the right c# code for getting the values after a PRAGMA table_info query.

Since my edit with extra code was rejected in this post, I made this question for other people that would otherwise waste hours for a fast solution.

Community
  • 1
  • 1
e-motiv
  • 5,795
  • 5
  • 27
  • 28
  • And you didn't answer the question because? (or add a comment to the answer you link to, which probably would have been better) – lc. Jul 18 '13 at 07:59
  • You mean this question (1) or the other (2)? 1: Because stackoverflow only lets me do that after 2 hours (which I only realized after making the question). 2: Because the answer would have been double (and thus an edit is better) – e-motiv Jul 20 '13 at 09:25

3 Answers3

14

Assuming you want a DataTable with the list of field of your table:

 using (var con = new SQLiteConnection(preparedConnectionString))
    {
       using (var cmd = new SQLiteCommand("PRAGMA table_info(" + tableName + ");"))
        {
            var table = new DataTable();

            cmd.Connection = con;
            cmd.Connection.Open();

             SQLiteDataAdapter adp = null;
                try
                {
                    adp = new SQLiteDataAdapter(cmd);
                    adp.Fill(table);
                    con.Close();
                    return table;
                }
              catch (Exception ex)
              { }
         }
     }

Return result is:

  • cid: id of the column
  • name: the name of the column
  • type: the type of the column
  • notnull: 0 or 1 if the column can contains null values
  • dflt_value: the default value
  • pk: 0 or 1 if the column partecipate to the primary key

If you want only the column names into a List you can use (you have to include System.Data.DataSetExtension):

 return table.AsEnumerable().Select(r=>r["name"].ToString()).ToList();

EDIT: Or you can avoid the DataSetExtension reference using this code:

using (var con = new SQLiteConnection(preparedConnectionString))
      {
          using (var cmd = new SQLiteCommand("PRAGMA table_info(" + tableName + ");"))
          {
              var table = new DataTable();
              cmd.Connection = con;
              cmd.Connection.Open();

              SQLiteDataAdapter adp = null;
              try
              {
                  adp = new SQLiteDataAdapter(cmd);
                  adp.Fill(table);
                  con.Close();
                  var res = new List<string>();
                  for(int i = 0;i<table.Rows.Count;i++)
                      res.Add(table.Rows[i]["name"].ToString());
                  return res;
              }
              catch (Exception ex){ }
          }
      }
      return new List<string>();

There are a lot of PRAGMA statements that you can use in SQLite, have a look at the link.

About the using statement: it's very simple, it is used to be sure that disposable objects will be disposed whatever can happen in your code: see this link or this reference

Community
  • 1
  • 1
Tobia Zambon
  • 7,479
  • 3
  • 37
  • 69
  • I'm sorry, but I was going to answer my own question. (Since I didn't want other people to get stuck like I was before finding this.) You were too fast for that. (And I can only do that after 2 days.) – e-motiv Jul 18 '13 at 08:06
  • You had to edit your previous question giving the complete solution, not to post another question. :-/ – Tobia Zambon Jul 18 '13 at 08:10
  • The previous question isn't mine. – e-motiv Jul 20 '13 at 09:27
  • You didn't really put a way to get the info out of the DataTable, except via the DataSetExtension. So, I did take my own answer after all. I do wonder why you keep using "using" though. Also, about your last comment, rereading it now, I wonder if you mean something else with "previous question" than I. Please clarify. If needed, I am willing to change my actions. – e-motiv Aug 09 '13 at 10:43
  • trippino if you add an alternate solution for getting it in a List without DataSetExtension (something like in my answer) and add the PRAGMA info too somewhere and maybe some comment about "using", I'll change my accepted answer to your answer, since it's much nicer then. – e-motiv Nov 01 '13 at 10:18
  • To use the foreach you have to cast the inner `DataRowCollection` as an `Enumerable` so you will have to include the `DataSetExtension` reference – Tobia Zambon Nov 04 '13 at 12:33
  • 1
    I see! So my compiler was including it without my knowledge! Thanks for that info. (Not that I am against that DataSetExtension that much; just thought it would be a bit less overhead without much knowledge of it.) In other words: You know your stuff! Thanks again! – e-motiv Nov 05 '13 at 12:59
1

Code:

DB = new SQLiteConnection(@"Data Source="+DBFileName);
DB.Open();
SQLiteCommand command = new SQLiteCommand("PRAGMA table_info('tracks')", DB);
DataTable dataTable = new DataTable();
SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(command);
dataAdapter.Fill(dataTable);
DB.Close();
foreach (DataRow row in dataTable.Rows) { 
    DBColumnNames.Add((string)row[dataTable.Columns[1]]); }  
            //Out(String.Join(",", 
    DBColumnNames.ToArray()));//debug

All elements in the resulted rows:
int cid, string name, string type,int notnull, string dflt_value, int pk

More info on PRAGMA

e-motiv
  • 5,795
  • 5
  • 27
  • 28
-1

Not sure if this exactly what you are after but this is how I have grabbed the data and subsequently used it. Hope it helps! Obviously the switch is not covering all eventualities, just those I have needed to so far.

    /// <summary>
    ///  Allows the programmer to easily update rows in the DB.
    /// </summary>
    /// <param name="tableName">The table to update.</param>
    /// <param name="data">A dictionary containing Column names and their new values.</param>
    /// <param name="where">The where clause for the update statement.</param>
    /// <returns>A boolean true or false to signify success or failure.</returns>
    public bool Update(String tableName, Dictionary<String, String> data, String where)
    {
        String vals = "";
        Boolean returnCode = true;

        //Need to determine the dataype of fields to update as this affects the way the sql needs to be formatted
        String colQuery = "PRAGMA table_info(" + tableName + ")";
        DataTable colDataTypes = GetDataTable(colQuery);


        if (data.Count >= 1)
        {

            foreach (KeyValuePair<String, String> pair in data)
            {

                DataRow[] colDataTypeRow = colDataTypes.Select("name = '" + pair.Key.ToString() + "'");

                String colDataType="";
                if (pair.Key.ToString()== "rowid" || pair.Key.ToString()== "_rowid_" || pair.Key.ToString()=="oid")
                {
                    colDataType = "INT";
                }
                else
                {
                    colDataType = colDataTypeRow[0]["type"].ToString();

                }
                colDataType = colDataType.Split(' ').FirstOrDefault();
                if ( colDataType == "VARCHAR")
                {
                    colDataType = "VARCHAR";
                }

                switch(colDataType)
                {
                    case "INTEGER": case "INT": case "NUMERIC": case "REAL":
                            vals += String.Format(" {0} = {1},", pair.Key.ToString(), pair.Value.ToString());
                            break;
                    case "TEXT": case "VARCHAR": case "DATE": case "DATETIME":
                            vals += String.Format(" {0} = '{1}',", pair.Key.ToString(), pair.Value.ToString());
                            break;

                }
            }
            vals = vals.Substring(0, vals.Length - 1);
        }
        try
        {
            string sql = String.Format("update {0} set {1} where {2};", tableName, vals, where);
            //dbl.AppendLine(sql);
            dbl.AppendLine(sql);
            this.ExecuteNonQuery(sql);
        }
        catch(Exception crap)
        {
            OutCrap(crap);
            returnCode = false;
        }
        return returnCode;
    }
Andrew Seabrook
  • 397
  • 2
  • 17
  • Well I am so sorry about this I thought the point of the question was how to obtain the the column types >Is there some command like"show columns from TABLENAME"? I need something to just see the table structure. – Andrew Seabrook Aug 11 '13 at 10:18