SQLite, create a table with a variable name in C# - c#

I searched for an answer but the only solutions I found didn't work for SQLite.
I want to create different tables in my SQLite database with the name and columns defined by the user who creates the table.
I'm working on a project where users can test their knowledge of a language by creating a list that can be tested later. The list should be saved in a database as an apart table.
Image of the UI
So I want to save each list in the database with the table name equal to the "txtNaamLijst.Text" textbox.
Beside that I want the columns to have the name of "txtTaal1.Text" en "txtTaal2.Text" as defined by the user.
The script that I have written doesn't work. Scripts I found on the web did not work either. I have to write my SQLite commands in a single line because I use C#:
protected void btnSave_Click(object sender, EventArgs e)
{
using (System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection("Data Source=C:/Users/elias/Documents/Visual Studio 2017/WebSites/WebSite7/App_Data/overhoren.db"))
{
using (System.Data.SQLite.SQLiteCommand cmd = new System.Data.SQLite.SQLiteCommand(conn))
{
string naam = txtNaamLijst.Text;
string taal1 = txtTaal1.Text;
string taal2 = txtTaal2.Text;
string veld1 = txtVeld1.Text;
string veld1v2 = txtVeld1v2.Text;
string veld2 = txtVeld2.Text;
string veld2v2 = txtVeld2v2.Text;
string veld3 = txtVeld3.Text;
string veld3v2 = txtVeld3v2.Text;
string veld4 = txtVeld4.Text;
string veld4v2 = txtVeld4v2.Text;
string veld5 = txtVeld5.Text;
string veld5v2 = txtVeld5v2.Text;
string veld6 = txtVeld6.Text;
string veld6v2 = txtVeld6v2.Text;
conn.Open();
cmd.CommandType = System.Data.CommandType.Text;
cmd.Parameters.AddWithValue("#naam", naam);
cmd.Parameters.AddWithValue("#taal1", taal1);
cmd.Parameters.AddWithValue("#taal2", taal2);
cmd.Parameters.AddWithValue("#veld1", veld1);
cmd.Parameters.AddWithValue("#veld1v2", veld1v2);
cmd.Parameters.AddWithValue("#veld2", veld2);
cmd.Parameters.AddWithValue("#veld2v2", veld2v2);
cmd.Parameters.AddWithValue("#veld3", veld3);
cmd.Parameters.AddWithValue("#veld3v2", veld3v2);
cmd.Parameters.AddWithValue("#veld4", veld4);
cmd.Parameters.AddWithValue("#veld4v2", veld4v2);
cmd.Parameters.AddWithValue("#veld5", veld5);
cmd.Parameters.AddWithValue("#veld5v2", veld5v2);
cmd.Parameters.AddWithValue("#veld6", veld6);
cmd.Parameters.AddWithValue("#veld6v2", veld6v2);
cmd.CommandText = "CREATE TABLE IF NOT EXISTS #naam (#taal1 VARCHAR(50), #taal2, VARCHAR(50))";
cmd.CommandText = "INSERT INTO #naam (#taal1, #taal2) SELECT #veld1 , #veld1v2 UNION ALL SELECT #veld2 , #veld2v2 UNION ALL SELECT #veld3 , #veld3v2 UNION ALL SELECT #veld4 , #veld4v2 UNION ALL SELECT #veld5 , #veld5v2 UNION ALL SELECT #veld6 , #veld6v2";
cmd.Connection = conn;
cmd.ExecuteNonQuery();
conn.Close();`
}
}
}

In both your queries you use #naam as the parameter for the table name.
cmd.CommandText = "CREATE TABLE IF NOT EXISTS #naam..."
cmd.CommandText = "INSERT INTO #naam..."
cmd.Parameters.AddWithValue("#naam", naam);
Unfortunately, parameterizing table names is not possible. User Soner Gönül put it well in this answer. He has quite a bit of information but the gist of it is:
You can not parameterize your table names, column names or any other databse objects. You can only parameterize your values.
Now, it is possible to use plain old string concentration/formatting to have a variable table name, but that is NOT a good idea, as it leaves you vulnerable to SQL injection.

Related

MS Access - C# - Retrieve the latest inserted guid

Is there a way to retrieve the latest inserted guid in access with C#?
I tried this: Created a table Cars with a field Id of type autonumber, replicationID and a field Name varchar(250).
var command = myConnection.CreateCommand();
command.Connection.Open();
command.CommandText = "INSERT INTO Cars(Name) VALUES ('Pagani')";
command.ExecuteNonQuery();
command = context.Database.Connection.CreateCommand();
command.CommandText = "SELECT ##Identity";
Console.WriteLine(command.ExecuteScalar());
command.Connection.Close();
The issue which I am getting is:
Console.WriteLine(command.ExecuteScalar());
always shows 0
EDIT
To create the table you can use this statement over the C# OleDb connection (I think that from MS Access query does not work)
CREATE TABLE [Cars] (
[Id] guid not null DEFAULT GenGUID(),
[Name] text null
);
ALTER TABLE [Cars] ADD CONSTRAINT [PK_Cars_6515ede4] PRIMARY KEY ([Id])
I know this is not exactly what you are asking for, but let me suggest an alternative solution which might solve your underlying problem.
Create the GUID in C# and pass it to your insert:
var newGuid = Guid.NewGuid();
var command = myConnection.CreateCommand();
command.Connection.Open();
command.CommandText = "INSERT INTO Cars(Id, Name) VALUES (?, 'Pagani')";
command.Parameters.AddWithValue("#Id", newGuid); // Note: OleDb ignores the parameter name.
command.ExecuteNonQuery();
Console.WriteLine(newGuid);
GUIDs are unique. It really doesn't matter whether it is generated by your application or by the Access database driver.
This option is in all respects superior to reading the GUID afterwards:
You only need one database access.
It's less code.
It's easier.
And you can still omit the GUID in your INSERT in cases where you don't need to know the GUID - no need to change existing code.
If SELECT ##IDENTITY does not work for "ReplicationID" AutoNumber fields then the most likely way to retrieve such a value for a new record is to use an Access DAO Recordset insert, like this:
// required COM reference:
// Microsoft Office 14.0 Access Database Engine Object Library
var dbe = new Microsoft.Office.Interop.Access.Dao.DBEngine();
Microsoft.Office.Interop.Access.Dao.Database db = dbe.OpenDatabase(
#"C:\Users\Public\Database1.accdb");
Microsoft.Office.Interop.Access.Dao.Recordset rst = db.OpenRecordset(
"SELECT [Id], [Name] FROM [Cars] WHERE FALSE",
Microsoft.Office.Interop.Access.Dao.RecordsetTypeEnum.dbOpenDynaset);
rst.AddNew();
// new records are immediately assigned an AutoNumber value ...
string newReplId = rst.Fields["Id"].Value; // ... so retrieve it
// the returned string is of the form
// {guid {1D741E80-6847-4CB2-9D96-35F460AEFB19}}
// so remove the leading and trailing decorators
newReplId = newReplId.Substring(7, newReplId.Length - 9);
// add other field values as needed
rst.Fields["Name"].Value = "Pagani";
// commit the new record
rst.Update();
db.Close();
Console.WriteLine("New record added with [Id] = {0}", newReplId);
which produces
New record added with [Id] = 1D741E80-6847-4CB2-9D96-35F460AEFB19
You can try like this using the OUTPUT :
INSERT INTO myTable(myGUID)
OUTPUT INSERTED.myGUID
VALUES(GenGUID())
You can try like this:
string str1 = "INSERT INTO Cars(Name) VALUES ('Pagani')";
string str2 = "Select ##Identity";
int ID;
using (OleDbConnection conn = new OleDbConnection(connect))
{
using (OleDbCommand cmd = new OleDbCommand(str1, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
cmd.CommandText = str2;
ID = (int)cmd.ExecuteScalar();
}
}

How to display values into gridview from sql databese

In my database i have three tables. One For employs where i keep their names, ids, salary... In the second one named Project i keep id, location, name. in the third one named WorksOn i keep the id from employs and the id from project. In my Asp .Net web site in gridview i need to display the employee's name and the name of the project that he is working.
string connect =
WebConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
SqlConnection con = new SqlConnection(connect);
try
{
con.Open();
}
catch (Exception err)
{
string error = err.Message;
con.Close();
}
SqlCommand command = new SqlCommand();
command.Connection = con;
SqlDataReader reader;
command.CommandText = "SELECT * FROM WorksON ";
reader= command.ExecuteReader();
In data source in gridview if i choose to display the values from WorksOn table it shows the id from employs and the id from project but what i need is to show the names on the employs and project.
I know that i need to do something with dataset but i don't know who.
Your SQL command must JOIN the related tables. Something like:
SELECT * FROM WorksOn JOIN Employee on WorksOn.EmployeeId = Employee.Id
Note that you should not SELECT "*" (all columns). You should only SELECT those columns that are necessary to your data view for performance.
On your SQL command, you don't mention anything about Employs. You need to use a JOIN SQL command in order to get both the employee name and the company name.
And instead of using "SELECT * FROM...", consider using the columns name instead, because you're not trying to get all the columns display. And it will help us understand the name of the columns to further help you.
Use a JOIN query like this:
SELECT project.projectName, employee.Name
FROM (worksOn
INNER JOIN employee
ON (worksOn.employeeId = employee.employeeId))
INNER JOIN project
ON (project.projectId = employee.employeeId)
AND (worksOn.projectId = project.projectId)

SQL server - inserting a string with a single quotation mark

I iterate over an external source and get a list of strings. I then insert them into the DB using:
SqlCommand command = new SqlCommand(commandString, connection);
command.ExecuteNonQuery();
Where commandString is an insert into command. i.e.
insert into MyTable values (1, "Frog")
Sometimes the string contains ' or " or \ and the insert fails.
Is there an elegant way to solve this (i.e. #"" or similar)?
Parameters.
insert into MyTable values (#id, #name)
And
int id = 1;
string name = "Fred";
SqlCommand command = new SqlCommand(commandString, connection);
command.Parameters.AddWithValue("id", id);
command.Parameters.AddWithValue("name", name);
command.ExecuteNonQuery();
Now name can have any number of quotes and it'll work fine. More importantly it is now safe from sql injection.
Tools like "dapper" (freely available on NuGet) make this easier:
int id = 1;
string name = "Fred";
connection.Execute("insert into MyTable values (#id, #name)",
new { id, name });
You should look into using parameterized queries. This will allow you insert the data no matter the content and also help you avoid possible future SQL injection.
http://csharp-station.com/Tutorial/AdoDotNet/Lesson06
http://www.c-sharpcorner.com/uploadfile/puranindia/parameterized-query-and-sql-injection-attacks/

C# and SQL SELECT

Currently I am working on a project regarding C# and SQL and I have a problem regarding the SELECT function and I cannot find any solutions on-line.
The scenario is regard searching query from C# through SQL server and display the results in a Data Grid View at C#.
I'm using Visual Studio 2008 and SQL Server Studio 2008.
Before starting the project I just did a quick Windows form from Visual studio and just did a datagridview, 2 text boxes and a Search Button.
At SQL Server I have a a database with a table DVD and I want to search, from this Windows form with the DVD ID and Name.
I started with the DVD ID and implemented this code :
private void btnView_Click(object sender, EventArgs e)
{
SqlConnection c = new SqlConnection(#"Data Source=GILBERTB-PC\SQLEXPRESS;Initial Catalog=DVDandGameBooking;Integrated Security=True");
DataTable t = new DataTable();
string sqlString = "SELECT * From DVD where Id ='" + txtID.Text+ "'";
SqlDataAdapter dt = new SqlDataAdapter(sqlString, c);
dt.Fill(t);
dtgv1.DataSource = t;
}
and it worked :)
Then I changed the code to
string sqlString = "SELECT * From DVD where Name ='" + txtName.Text+ "'";
so that I can search with Name of the DVD but when I started the program and searched with the Name it just showed a blank database
Also is there any way that I can change the code so that I can either search with the ID or with the Name ?
Thanks for your help and time
Thoughts:
Make sure txtName.Text has a value
Try SQL select using Enterprise Manager, Toad, or some other query tool. What do you get?
Try using LIKE as example below
Worst case, maybe check the Collation for the Table, perhaps its set to 'Case Sensitive' text matching.
Both ID and Name:
SELECT * FROM DVD
WHERE Id=[ID Value]
OR Name LIKE '%[Name Value]%'
Or you could use SQLCommand with parameters like this:
SqlConnection c = new SqlConnection(#"Data Source=GILBERTB-PC\SQLEXPRESS;Initial Catalog=DVDandGameBooking;Integrated Security=True");
string queryString = "SELECT * From DVD where Id = #id";
var paramId = new SqlParameter("id", SqlDbType.VarChar);
var query = new SqlCommand(queryString, c);
query.Parameters.Add(paramId);
If you really want to use an SQLDataAdapter, you can set the select command to the one I wrote above. Otherwise, you can use a dataReader and iterate through the results.
Also, using parameters like this makes your query easier to read and makes it safer to SQL injections. It should always be considered.
Edit1: If you want to search with either the Id or the Name, you can just make 2 parameters, and put an OR between the 2, and maybe use the keyword like instead of = in your query. If the values can be null, you may want to build your query dynamically, depending on the values that are not null.

Read\Write\Change MySql Table from asp.net list view

so, i am building a new website for my brother and it seems that i need to use MySql for him.
In ASP.NET there is a list view item, that you can choose from which DB is will take the info and you can Read \ Write \ Change \ Delete with a click of a button.
any one here know how can i do that with MySql ? and not mssql.. i know how to use DataBases, i just didnt ever worked with MySql and i will be thankfull for anyone who will help me.
Thanks again! alon.. :)
You first need a connector which you can find here
Then instead of using System.Data classes use the one you just downloaded. They are the same classes, but the only difference is that they are for MySQL.
Furthermore if you want to write MySQL queries, well they are pretty much the same as in MSSQL. Here are some examples:
Read:
SELECT id, value FROM table
WHERE id = 16;
Write:
INSERT INTO table(id, value)
VALUES (1,'Bob'),(2,'Betty');
Change:
UPDATE table
SET id = 7
WHERE id = 16;
Delete:
DELETE FROM table
WHERE id = 7;
And in your C# code you just need to use 3-4 classes to work with the database. Since I don't want to make this a wall of text, you can read more about those classes here , unless you are familiar enough with those.
Here is a general approach to do basic operations with mysql database. I assume that you know how to setup your mysql database. if not you can find many info about it on google. I also assumed that you have a table on your mysql database named "table" which has following columns: id, name, address.
// Connection String
private const string ConnStr =
"Driver={MySQL ODBC 3.51 Driver};Server=localhost;" +
"Database=test;uid=root;pwd=;option=3";
// DataBinding
private void BindDataGrid()
{
using(OdbcConnection con = new OdbcConnection(ConnStr))
using(OdbcCommand cmd =
new OdbcCommand("SELECT * FROM Sample", con))
{
con.Open();
DataGrid1.DataSource = cmd.ExecuteReader(
CommandBehavior.CloseConnection |
CommandBehavior.SingleResult);
DataGrid1.DataBind();
}
}
// Insert Operation
private void InsertInfo()
{
if(CheckIsAddNameValid())
{
HtmlTable2.Visible = false;
using(OdbcConnection con = new OdbcConnection(ConnStr))
using(OdbcCommand cmd = new OdbcCommand("INSERT INTO sample" +
"(name, address) VALUES (?,?)", con))
{
cmd.Parameters.Add("#name", OdbcType.VarChar,
255).Value = TextBox3.Text.Trim();
cmd. Parameters.Add("#address", OdbcType.VarChar,
255).Value = TextBox4.Text.Trim();
con.Open();
cmd.ExecuteNonQuery();
BindDataGrid();
}
}
}
// Update Operation
private void UpdateInfo(int id, string name, string address)
{
using(OdbcConnection con = new OdbcConnection(ConnStr))
using(OdbcCommand cmd = new OdbcCommand("UPDATE sample " +
"SET name = ?, address = ? WHERE ID = ?", con))
{
cmd.Parameters.Add("#name", OdbcType.VarChar, 255).Value = name;
cmd.Parameters.Add("#address",
OdbcType.VarChar, 255).Value = address;
cmd.Parameters.Add("#ID", OdbcType.Int).Value = id;
con.Open();
cmd.ExecuteNonQuery();
}
}
// Update Operation
private void DeleteInfo(int id)
{
using(OdbcConnection con = new OdbcConnection(ConnStr))
using(OdbcCommand cmd = new OdbcCommand("DELETE " +
"FROM sample WHERE ID = ?", con))
{
cmd.Parameters.Add("#ID", OdbcType.Int).Value = id;
con.Open();
cmd.ExecuteNonQuery();
}
}
if you do not have a table on your database use this script to create the database in this example:
CREATE TABLE sample (
id int AUTO_INCREMENT NOT NULL,
name varchar(45) NOT NULL,
address varchar(45) NOT NULL,
PRIMARY KEY(id)
)
GO
BindDataGrid function shows the result of the query in datagrid. In general you can put the result of any query to a list and then bind it to the datagrid with the following code:
List<string> AllStudents = getAllStudents();
dataGrid1.datasource = AllStudents;
dataGrid1.databind();
ASP.Net works with database through the Provider Model. You you have downloaded the ADOconnector for MySql, it should work the same way as how it is with MS SQL, except that you have to use different set of queries specific to MySql.
You might also try looking into the Entity Framework. It is an object-relational-mapper (ORM) which abstracts the tables of a database into objects that you can easily work with in code. It makes code much more readable and maintainable than hardcoding SQL strings (as some of the other answers suggest).
The Entity Framework is Microsoft's recommended solution. You can use it with the MySQL connector that Bosak pointed out.
NHibernate is another popular ORM you might want to look into.

Categories

Resources