C# claims my SQLite table doesn't exist but it does - c#

I'm trying to read a table I created with DB Browser for SQLite, but there's a runtime error claiming the database doesn't have the table. But it does! I created it and I can see it in DB Browser.
Here's the code:
private void PopulateGridCustomers()
{
String conString = Properties.Resources.database;
var con = new SqliteConnection(conString);
try
{
con.Open();
Console.WriteLine(con.State);
SqliteCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT * FROM Clientes";
using (SqlCeDataAdapter dataAdapter = new SqlCeDataAdapter(cmd.CommandText, conString))
{
DataTable dt = new DataTable();
dataAdapter.Fill(dt);
gridCustomers.DataSource = dt;
}
}
And a picture showing the table exists indeed:
What could be causing this issue and how to fix it?
Thanks
P.S.: Please cut me some slack, I'm not a professional developer. I code for myself.
Update: Here's the actual error message:
System.Data.SqlServerCe.SqlCeException: 'The specified table does not exist.
[ Clientes ]'
UPDATE 2:
Here's the path of the database:
Data Source=C:\Users\charl\OneDrive\Documentos\SBM\Database\SBMTeste.db;
As you can see, it is the very same that shows in DB Browser window. The error I first described occurs if I omit the ".db". If I put the file extension in the string, the following error is thrown:
System.Data.SqlServerCe.SqlCeException: 'The database file may be corrupted.
Run the repair utility to check the database file.
[ Database name = C:\Users\charl\OneDrive\Documentos\SBM\Database\SBMTeste.db ]'
UPDATE 3:
Here's the CREATE statement of the table:
CREATE TABLE "Clientes" (
"id" INTEGER NOT NULL UNIQUE,
"nome" TEXT NOT NULL,
"telefone1" TEXT,
"telefone2" TEXT,
"email" TEXT,
"endereço" TEXT,
"bairro" TEXT,
"cidade" TEXT,
"data_nascimento" TEXT,
"data_cadastro" TEXT DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY("id" AUTOINCREMENT),
UNIQUE("nome","data_nascimento")
)

The thing is I messed up when trying to install the packages needed for my application to work with the SQlite database. I endend up installing a lot of unnecessary things and missing using System.Data.SQLite. That way my application was not being able to recognize the .db file hence the "corrupted file" message described in my 3rd update.

SQL Server CE is not SQLite.
This is an extract of my code using SQLite:
public Equity SearchEquityByEpic(string epic)
{
string query = string.Format("SELECT * from " + Tables.ASSETS_TABLE + " WHERE epic='{0}'", epic);
Log(query);
var command = _connection.CreateCommand(query);
var equities = command.ExecuteQuery<Equity>();
if (equities.Count == 0)
{
return null;
}
Equity ret = equities.First();
return ret;
}

Related

MySQL server error - You have an error in your SQL syntax

I'm trying to update a Database table and getting the error
"MySql.Data.MySqlClient.MySqlException: 'You have an error in your SQL
syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near 'group='superadmin' WHERE
identifier='steam:steam:1100001098b5888'' at line 1'"
// Creates query to run
public void UpdateInfo(String jobTitle, int jobGrade, String adminLevel, String identifier) {
// Opens the database connection if it's not already open
if (!(databaseConnected)) {
openConnection();
}
// Creates query to run
String query = "UPDATE " + table + " SET job=#jobTitle, job_grade=#jobGrade, group=#adminLevel WHERE identifier=#identifier";
// Makes a new command
MySqlCommand cmd = new MySqlCommand(query, connection);
// Replaces the # placeholders with actual variables
cmd.Parameters.AddWithValue("#jobTitle", jobTitle);
cmd.Parameters.AddWithValue("#jobGrade", jobGrade);
cmd.Parameters.AddWithValue("#adminLevel", adminLevel);
cmd.Parameters.AddWithValue("#identifier", identifier);
// Executes it and if it's...
if (cmd.ExecuteNonQuery() > 0) {
// Successful
MessageBox.Show("Successfully updated information");
closeConnection();
return;
} else {
// Not successful
MessageBox.Show("Error with updating information!");
// Closes the connection again to prevent leaks
closeConnection();
return;
}
}
I tried your query on https://sqltest.net/ and noticed it highlighted "group" when I tried to create the table. I'm wondering if the problem might be the usage of "group" as a column name since it's a reserved word.
Is it possible to try renaming the column to group_level or adding back ticks around 'group' or "group" and seeing if that works?
So for example
'group'=#grouplevel
I found this thread and this thread on renaming the column where they had issues with "group" as a column name. Adding backticks seemed to solve both problems.
EDIT: As per OP, double quotes (") solved the issue instead of single. Edited answer to include.
Try change query like this
String query = "UPDATE " + table + " SET job='#jobTitle', job_grade=#jobGrade, group='#adminLevel' WHERE identifier='#identifier'";
if you input String value with query, you need to use 'this' for work
I hope this will work for you.
if not, you can use String.Format for that like this.
String Query = String.Format("Update `{0}` Set job='{1}', job_grade={2}, group='{3}' Where identifier='{4}'", table, jobTitle, jobGrade, adminLevel, identifier);

Error with adding records to SQL Server database (nvarchar)

I am trying to add records to a SQL Server database. The connection works fine for any other table except one.
This is my code:
private void saveCurrent()
{
try
// Save entry into the database.
{
string query = "INSERT INTO entries VALUES (#Date, #Tags, #Entry, #User)";
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
{
connection.Open();
command.Parameters.AddWithValue("#Date", System.DateTime.Now.ToLongDateString());
command.Parameters.AddWithValue("#Tags", txtTags.Text);
command.Parameters.AddWithValue("#Entry", richEntryBox.Text);
command.Parameters.AddWithValue("#User", Form1.userName);
command.ExecuteNonQuery();
isDirty = false;
}
}
catch (Exception exception)
{
MessageBox.Show("There was an error saving this entry: " + exception.ToString());
}
The error is:
System.Data.SqlClient.SqlException (0x8-131904): Column name or number of supplied values does not match table definition.
All of the columns are of type nvarchar(50) and nvarchar(MAX). I am trying to enter just text information, no binaries. The dataset shows that the table has a "photos" column, but it can be null and I'm not using it (for some reason, I cannot get VS2017 to delete that column). I have altered the dataset to not include the "photos" field, but still receiving the error. Any push to the solution would be appreciated. A snap of the dataset is included here.
My dataset, in which I've removed the photos column:
--S
If your database still has the photos field, you'll need to specify the columns for insertion explicitly.
So change your insert to:
string query = "INSERT INTO entries (date, tags, entry, user) VALUES (#Date, #Tags, #Entry, #User)";
In general, you want to be explicit with your insertions. What would happen if someone added a column after tags and before entry in the database? This would break your code.

SqlDataReader's Read() function returns empty row, same query returns value from database browser

I have a table in SQLite with the following structure:
+-------+------+------+
| id |name |value |
|int |text |int |
+-------+------+------+
I am attempting to follow this guide on using sqlite databases in Unity. I am able to query the sqlite_master table to retrieve the only database table name using the following code:
_dbConnection = (IDbConnection)new SqliteConnection(_dbURI);
_dbConnection.Open();
string sqlStatement = "SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "';";
_dbCommand = _dbConnection.CreateCommand();
_dbCommand.CommandText = sqlStatement;
_dbReader = _dbCommand.ExecuteReader();
while (_dbReader.Read())
{
Debug.Log("Table: " + _dbReader.GetString(0));
}
However, when I attempt to query from the table itself to get the maximum ID using similar code my DataReader returns a null row:
_dbConnection = (IDbConnection)new SqliteConnection(_dbURI);
_dbConnection.Open();
string sqlStatement = "SELECT max(id) FROM " + tableName + ";";
_dbCommand = _dbConnection.CreateCommand();
_dbCommand.CommandText = sqlStatement;
_dbReader = _dbCommand.ExecuteReader();
while (_dbReader.Read())
{
Debug.Log("MaxId = " + _dbReader.GetInt32(0));
}
The null causes a conversion error with the call to _dbReader.GetInt32(0). When I write the sql statement to the log and paste it into my database browser it yields a number, so the query should be returning a value.
I'm not clear on why similar code works when querying sqlite_master but not my other table.
I've also tried ExecuteScalar with no success.
Thanks!
EDIT:
tableName is equal to "unit_def"
error message is
InvalidCastException: Cannot cast from source type to destination type.
Mono.Data.Sqlite.SqliteDataReader.VerifyType (Int32 i, DbType typ)
using count(*) yields a 0, so it seems that unity can't see the data in the table?
Also, oddly, changing the code messed up the GUI elements in my editor for some reason.
I solved the issue, hopefully this answer is helpful to others:
The issue was tricky to troubleshoot since
the correct database was being referenced
all code was correct
the sql query did return a result when run in my database browser
The problem is that I am using the DB Browser for Sqlite, which I am new to. I had written rows of data to the database so that my query would return results within the browser, but apparently these changes are not written to the database file for other applications to see until the "Write Changes" button is pushed.
Hopefully this helps anyone else who might be new to the db browser and stumbles into this error!

UWP - Check if table exists

There is a lack of documentation for SQLite in C# on the SQLite website related to the "SQLite for Universal Windows Platform" extension available in VS2015.
Has anyone seen any documentation specific to this extension?
I am trying to see whether a table exists in my DB but cannot find a method to do this.
This is what I am doing and why:
SQLite.Net.SQLiteConnection conn;
string path = path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "entries.sqlite");
if (!System.IO.File.Exists(path))
{
conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path);
conn.CreateTable<Entry>();
}
else
{
conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path);
}
I do this because when this is executed:
conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path);
The file is created if it does not exist. So first I need to test whether it exists. My assumption is that if the file exists, my table exists, because there is no scenario where the table is not created right after the file is created.
Am I missing some more direct way of testing for the table within the scope of the methods provided?
Thanks!
PS. I have checked whether my question has been answered but have not found anything related directly to this API.
You can use a query of the system sqlite_master table to see if a table with a given name exists:
var tableQuery = "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='Entry';"
bool tableExists = conn.ExecuteScalar<int>( tableQuery ) == 1;
If the table is not present, the query will return 0, if it is present, it will return 1.
However, you don't have to worry about calling conn.CreateTable<Entry>(); even when the table already exists. SQLite.net is smart enough to create the table only when it does not exist yet. If the table is already in the database, this call will be ignored.
Generic solution:
public bool TableIsExists<T>(SQLiteConnection conn)
{
var q = "SELECT name FROM sqlite_master WHERE type='table' AND name=?";
var cmd = conn.CreateCommand(q, typeof(T).Name);
return cmd.ExecuteScalar<string>() != null;
}

SQL Exception Error C# ASP.Net

It's been awhile since I've messed with anything SQL, and I'm trying to build a little Todo app to learn some ASP.Net with C#. I'm using Visual Studio 2013 with whatever version of SQL Express it comes packaged with, all locally.
I have the following table todo_list, made with the following script, through Visual Studio:
CREATE TABLE [dbo].[todo_list] (
[id] INT NOT NULL,
[task] TEXT NOT NULL,
[complete] BIT NOT NULL,
[date] DATE NOT NULL,
PRIMARY KEY CLUSTERED ([id] ASC)
);
When the web application starts, I'm trying to get all of the records where complete is false. I'm assuming I can read/write to the complete column as true/false because of it being of type bit.
I get an exception thrown when the following code goes to execute...
private void Get_Tasks()
{
//Get the connection string
SqlConnection connection = new SqlConnection();
connection.ConnectionString = System.Configuration.ConfigurationManager.
ConnectionStrings["Database1ConnectionString"].ConnectionString;
//Build SQL query
string query = "SELECT * FROM todo_list WHERE complete=False";
System.Diagnostics.Debug.WriteLine(query);
//Build SQL Command Object
SqlCommand command = new SqlCommand(query, connection);
//Grab all uncompleted tasks from database
SqlDataReader cursor;
try
{
using(connection)
{
//Open and execute SQL stuffz...
connection.Open();
cursor = command.ExecuteReader();
//Get all the tasks
while (cursor.Read())
{
//Build the task from record set
Todo task = new Todo(
(int)cursor["id"], (string)cursor["task"],
(bool)cursor["complete"], (DateTime)cursor["date"]);
//Append to DOM
Page.ClientScript.RegisterStartupScript(this.GetType(), "alert" + UniqueID, "alert('About to append to DOM!');", true);
tasklist.InnerHtml = task.toHtml();
}
//Close connection
connection.Close();
}
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.ToString());
connection.Close();
}
//TODO - Grab all completed tasks from database
}
The Exception that is thrown when cursor = command.ExecuteReader(); executes -
A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll'
System.Data.SqlClient.SqlException (0x80131904): Invalid column name 'False'.
I have no idea why it is taking False as a column name?
Thanks in advance for any help!
You can change the False for 0 or for 'False'
Example
Your SQL query is invalid. Did you read the error message?
Have you tried running in in SQL Server Management Studio (assuming your using SQL Server...if not, the interactive tools of choice)?
Your query
select *
from todo_list
where complete = False
is [trying to, anyway] selecting all the rows from the table todo_list where the table's two columns complete and False are equal. Since your table has no column named False, SQL Server's query compiler gives you the obvious error::
Invalid column name 'False'
SQL Server's bit datatype is not a boolean in the C# sense. It's fundamentally a 1-bit integer whose domain is {0,1}. You need to rephrase your query like this:
select *
from todo_list
where complete = 0
The CLR bidirectionally maps SQL Server's bit to a CLR System.Boolean. If the bit column is nullable, any SQL Server null values will be mapped to the sole instance of System.DbNull.

Categories