SQL Exception Error C# ASP.Net - c#

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.

Related

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

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

Alterations to SQL Server table don't seem to build in Visual Studio

I have a C# front-end to SQL Server back-end using Visual Studios 2017. When I initially created my table in the database, it was:
CREATE TABLE [dbo].[tblHazard_Reports]
(
[Id] INT PRIMARY KEY,
[Badge] INT NOT NULL,
[Full Name] VARCHAR NOT NULL
)
I have since changed it to
CREATE TABLE [dbo].[tblHazard_Reports]
(
[Id] INT IDENTITY(1, 1) PRIMARY KEY,
[Badge] INT,
[Full Name] VARCHAR(MAX)
)
However, when I run my SQLcmd.ExecuteNonQuery() statement, I'll either get the error that a column does not allow NULL or that a string or binary data will be truncated. Although everything in my project seems to show that my changes to the columns have been made, I get errors as if I never touched it.
I've looked online for a place to put a proper ALTER statement in Visual Studio, but I can't find anything. How can I rebuild my table to reflect the changes I've made?
Here is my C# code in case it is relevant.
private void InsertHazardItem(E3_Project.HazardItem currHaz)
{
using(SqlConnection cnn = new SqlConnection("connectionString"))
{
string commandString = "INSERT INTO tblHazard_Reports([ID], [Badge],
[Full Name]) VALUES(#ID, #Badge, #Name)";
using(SqlCommand command = new SqlCommand(commandString, cnn))
{
var parameterID = new SqlParameter("#ID", System.Data.SqlDbType.Int);
var parameterBadge = new SqlParameter("#Badge", System.Data.SqlDbType.Int);
var parameterName = new SqlParameter("#Name", System.Data.SqlDbType.VarChar);
parameterID.Value = currHaz.ID;
parameterBadge.Value = currHaz.Badge;
parameterName.Value = currHaz.Name;
command.Parameters.Add(parameterID);
command.Parameters.Add(parameterBadge);
command.Parameters.Add(parameterName);
cnn.Open()
command.ExecuteNonQuery(); //The error is always on this line
}
}
}
Note that the ID should be auto-incrementing, but I have it included here because, again, it doesn't seem that my change to the table has been built.
Since you defined the ID column as an IDENTITY column, the database takes care of setting that value when you INSERT a row. Try removing the ID column from your INSERT statement and it should work.
Unrequested Hint: You and everyone who ever uses your database will be much happier if you do not include spaces in your column names. [Full Name] would be better as FullName.
Alterations to a table must be done in code. In my case, I ended up using C# and ExecuteNonQuery to do so, as shown here.
Even new tables must be created with code and executed directly with code. Adding a new table to my database using the Visual Studio tools did not seem to actually show up and be used.

Return DateTime as VarChar for use in DataGridView

I wrote a simple database-application in Visual studio accessing a small database in XAMPP.
I want to fill a gridview with the contents of a date-field from a database.
The main problem i'm having here is the the CONVERT isnt working (syntax error), but i have the feeling there is a answer thats a lot simpler for the task of simply displaying a date.
Here is the Create of the table:
CREATE TABLE `lans` (
`l_id` INT(11) NOT NULL AUTO_INCREMENT,
`l_datum` DATE NOT NULL,
PRIMARY KEY (`l_id`),
UNIQUE INDEX `datum` (`l_datum`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2;
The Query im trying to run:
gridViewLans.DataSource = CLanDB.SQLOpen("select CONVERT(varchar,l_datum, 104) from lans").Tables[0].DefaultView;
And the function SQLOpen i wrote.
public static DataSet SQLOpen(String cSQL) {
MySqlCommand qCmd = oDB.CreateCommand();
qCmd.CommandText = cSQL;
MySqlDataAdapter adap = new MySqlDataAdapter(qCmd);
DataSet set = new DataSet();
adap.Fill(set);
return set;
}
The error i get:
SQL Fehler (1064): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'varchar(100), lans.l_datum, 104) as Lan from lans' at line 1
How do i resolve the syntax error?
The problem was a malformatted entry in the table.
Once i deleted that i could use
gridViewLans.DataSource = CLanDB.SQLOpen("select l_datum as LAN from lans").Tables[0];
and it worked finely.

Memory allocation error from MySql ODBC 5.1 driver in C# application on insert statement

I have a .NET Wndows application in C#. It's a simple Windows application that is using the MySql 5.1 database community edition. I've downloaded the MySql ODBC driver and have created a dsn to my database on my local machine. On my application, I can perform get type queries without problems, but when I execute a given insert statement (not that I've tried doing any others), I get the following error:
{"ERROR [HY001] [MySQL][ODBC 5.1 Driver][mysqld-5.0.27-community-nt]Memory allocation error"}
I'm running on a Windows XP machine. My machine has 1 GB of memory.
Anyone have any ideas? See code below
OdbcConnection MyConn = DBConnection.getDBConnection();
int result = -1;
try
{
MyConn.Open();
OdbcCommand myCmd = new OdbcCommand();
myCmd.Connection = MyConn;
myCmd.CommandType = CommandType.Text;
OdbcParameter userName = new OdbcParameter("#UserName", u.UserName);
OdbcParameter password = new OdbcParameter("#Password", u.Password);
OdbcParameter firstName = new OdbcParameter("#FirstName", u.FirstName);
OdbcParameter LastName = new OdbcParameter("#LastName", u.LastName);
OdbcParameter sex = new OdbcParameter("#sex", u.Sex);
myCmd.Parameters.Add(userName);
myCmd.Parameters.Add(password);
myCmd.Parameters.Add(firstName);
myCmd.Parameters.Add(LastName);
myCmd.Parameters.Add(sex);
myCmd.CommandText = mySqlQueries.insertChatUser;
result = myCmd.ExecuteNonQuery();
}
catch (Exception e)
{
//{"ERROR [HY001] [MySQL][ODBC 5.1 Driver][mysqld-5.0.27-community-nt]Memory
// allocation error"} EXCEPTION ALWAYS THROWN HERE
}
finally
{
try
{
if (MyConn != null) MyConn.Close();
}
finally { }
}
It was because some fields accept null, I had passed them as null where they should be passed as DBNull.Value. For all the fields which allow null should be checked for null and if found null, DBNull.Value should be passed.
Just for the sake of completeness, Chinjoo's SQL statement would likely be something like this:
mySqlQueries.insertChatUser = "insert into ChatUsers (UserName, Password, FirstName, LastName, sex) values (?,?,?,?,?);";
This is known as a parameterized insert where each question mark represents one of his parameters. In this simple example the order of the parameters in the parameter collection in code must match the order of the column names in the SQL statement.
While less elegant than using a function, the fix for his null problem would look something like this for one of his parameters:
OdbcParameter LastName = new OdbcParameter("#LastName", u.LastName);
is replaced with
// if the value is "null" return DBNull, else just the value
OdbcParameter LastName = new OdbcParameter("#LastName",
(u.LastName == null) ? System.DBNull.Value : (object)u.LastName);
At least in my code (which is slightly different) the inner cast to type object is required since otherwise the compiler isn't sure what type the ?: operator should return.
Hope this helps anyone who is relatively new to parameterization, etc.
No criticism of Chinjoo implied at all--his posting helped me out! Just thought I'd share for the less-experienced. I'm by no means expert so take everything I say with a grain of salt.
This exception also can be raised if you try to insert invalid chars in a VARCHAR field. In example, if the string is generated by a UNIX machine and has end of line characters '\n'. You can just replace that problematic characters to Windows style, or viceversa, or just delete it if you don't want to store end of lines.
You can check the strings, and if any of them has end of line characters, try to repeat the insert deleting them. If it works, the problem are these characters.

How to create "embedded" SQL 2008 database file if it doesn't exist?

I've created a database application using C#, ADO.Net and an embedded MS SQL 2008 database file (that attaches to MS SQL 2008 Express) which I created in Server Management Studio. Can someone point me to a resource that describes how I can programmatically create the database file if it is missing (like right after my application is installed)?
If it were me (when it is me...):
You don't particularly want to be trying to make database files work by copying them and attaching them - there are reasons why you might want to but I believe these to be exceptions rather than rules.
Accordingly what you need to do is to script creation of the database i.e. to use SQL DDL to create the database and the tables and all the other stuff in your schema.
Pretty much all you need to enable you to do this is appropriate rights to the server instance and then a connection string (which you can probably build apart from the server/instance name).
From here:
Is there a database? If not create it.
If there is a database, is it the right schema version? If too low either update it or advise the user and back out gracefully depending on how you want things too work. If too high just back out and advise that an updated version of the application is required
All is as it should be, carry on.
From a code point of view: method to determine if a database exists; method to create an standard "empty" database with a version table and a version number of 0; methods to bring the schema up to the current version by running the appropriate DDL (we encode ours into C# because it provides more flexibility but you could equally run DDL scripts in sequence).
Does it exist:
public virtual bool Exists()
{
bool exists = false;
string masterConnectionString = this.CreateConnectionString(this.Server, this.FailoverServer, "master");
this.DBConnection.ConnectionString = masterConnectionString;
this.DBConnection.Open();
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = this.DBConnection;
cmd.CommandText = "SELECT COUNT(name) FROM sysdatabases WHERE name = #DBName";
cmd.Parameters.AddWithValue("#DBName", this.DBName);
exists = (Convert.ToInt32(cmd.ExecuteScalar()) == 1);
}
finally
{
this.DBConnection.Close();
}
return exists;
}
Create a new database:
public virtual void CreateNew()
{
string createDDL = #"CREATE DATABASE [" + this.DBName + "]";
this.BuildMasterConnectionString();
this.DBConnection.Open();
try
{
this.ExecuteSQLStmt(createDDL, this.DefaultSQLTimeout, null);
}
finally
{
this.DBConnection.Close();
}
createDDL = #"
CREATE TABLE AAASchemaVersion
(
Version int NOT NULL,
DateCreated datetime NOT NULL,
Author nvarchar(30) NOT NULL,
Notes nvarchar(MAX) NULL
);
ALTER TABLE AAASchemaVersion ADD CONSTRAINT PK_Version PRIMARY KEY CLUSTERED
(
Version
);
INSERT INTO AAASchemaVersion
(Version, DateCreated, Author, Notes)
VALUES
(0, GETDATE(), 'James Murphy', 'Empty Database')
";
this.BuildConnectionString();
this.ConnectionString += ";pooling=false";
this.DBConnection.Open();
try
{
this.ExecuteSQLStmt(createDDL, this.DefaultSQLTimeout, null);
}
catch (Exception ex)
{
throw new Exception("Exception while creating / initialising AAASchemaVersion", ex);
}
finally
{
this.DBConnection.Close();
}
}
The update code is a tad more complex but basically runs stuff like this:
CREATE TABLE AuditUser
(
ID int IDENTITY(1,1) NOT NULL,
UserSourceTypeID tinyint NOT NULL,
DateCreated smalldatetime NOT NULL,
UserName nvarchar(100) NOT NULL
);
ALTER TABLE AuditUser
ADD CONSTRAINT
PK_AuditUser PRIMARY KEY CLUSTERED
(
ID
),
CONSTRAINT [FK_AuditUser_UserSourceType] FOREIGN KEY
(
UserSourceTypeID
) REFERENCES UserSourceType (
ID
);
All wrapped up in a transaction per update - so that if the update fails you should leave the database is a known good state.
Why do it this way (in code, which is not without its trials?) well the end result is a high degree of confidence that the schema your app is talking to is the schema your app expects to talk to... right tables, right columns (in the right order, that are the right type and the right length), etc, etc. and that this will continue to be the case over time.
Apologies if this is a bit long - but this is something I'm quite keen on...
If the "embedded MS SQL" is a "Microsoft SQL Server Compact 3.5":
using (SqlCeEngine sqlCeEngine = new SqlCeEngine(connectionString))
sqlCeEngine.CreateDatabase();

Categories