how to write mysql create table query in c# - c#

how to create table query in c# for mysql database..
MySqlConnection con = new MySqlConnection("Server=localhost;Database=demo_test;UID=root;Password= ");
MySqlCommand acmd = new MySqlCommand("CREATE TABLE first (" + a.Columns[0] + " int(20) NOT NULL auto_increment,'" + a.Columns[1].ToString() + "' varchar(100) NOT NULL default,PRIMARY KEY (" + a.Columns[0]+") 1", con);
con.Open();
acmd.ExecuteNonQuery();
it gives me an error
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 ''name' varchar(100) NOT NULL default,PRIMARY KEY (id) 1' at line
1

Instead of fighting with SQL directly, you could use Mig# like this:
var schema = new DbSchema(ConnectionString, DbPlatform.MySql5);
schema.Alter(db => db.CreateTable("first")
.WithPrimaryKeyColumn(a.Colunns[0], DbType.Int32).AsIdentity()
...);

It's because you are wrapping the column names with single quote which converts the value into string and not an identifier anymore. Remove the single quotes and it will work.
string query = #"CREATE TABLE first (" + a.Columns[0] + " int(20) NOT NULL auto_increment, "
+ a.Columns[1].ToString() + " varchar(100) NOT NULL default,
PRIMARY KEY (" + a.Columns[0]+")"

Related

Violation of PRIMARY KEY constraint SQL Server

string query = "UPDATE Completed_orders SET service=N'" + comboBox1.SelectedValue + "',kolvo=N'" + kol.Text + "',note=N'" + not.Text + "' WHERE orders='" + form3.ordersgrid.CurrentRow.Cells[0].Value.ToString() + "' ";
SqlCommand cmd = new SqlCommand(query, dataBase.getConnection());
dataBase.openConnection();
cmd.ExecuteNonQuery();
dataBase.closeConnection();
form3.serviceklient();
MessageBox.Show("Изменена");
this.Hide();
You try to add an occurence in a table when a record with the same id (primary key) already exist.
If it's possible for your project, I suggest you tu use a numeric ID with the autoincrement option :
CREATE TABLE `table_name` ( id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, [...] );
Auto-increment allows a unique number to be generated automatically when a new record is inserted into a table.
When you insert a new record in the table, you don't have to specify the id.

How to store c# decimal data type in an sqlite3 database?

I'm trying to store an c# datatype in a sqlite3 table and it gives an error.
"id INTEGER NOT NULL PRIMARY KEY, " +
"time DATETIME, " +
"total DECIMAL)
When trying to insert a value
string Sql = "INSERT INTO " + TableName + " (symbolId, time, total)"
+ string.Format("VALUES (#{0},#{1},#{2})",
(int)symbolId, time, total);
SqliteCommand command = new SqliteCommand(Sql, Connection);
command.ExecuteNonQuery();
When executing the query the error is the following:
What is the correct approach? Use text type instead?

Why is my call to LastInsertedId not returning the expected value?

I have MySql Tables with autoinc ID columns, such as "director_id" here:
CREATE TABLE directors (
director_id Integer NOT NULL AUTO_INCREMENT,
first_name VarChar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
middle_name VarChar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
last_name VarChar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
suffix VarChar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
PRIMARY KEY (
director_id
)
)
I want to store the autoincremented director_id value in the movies_main Table.
So I try to assign the autoincremented value to an int variable:
long director_id = 0;
...in the call to LastInsertedId here (last line):
if (!alreadyExists)
{
comm.Parameters.Clear();
comm.CommandText = "INSERT INTO Directors " +
"(first_name, middle_name, last_name, suffix) " +
"VALUES " +
"(#first_name, #middle_name, #last_name, #suffix)";
comm.Parameters.AddWithValue("#first_name", directorNamePartsList[0]);
comm.Parameters.AddWithValue("#middle_name", directorNamePartsList[1]);
comm.Parameters.AddWithValue("#last_name", directorNamePartsList[2]);
comm.Parameters.AddWithValue("#suffix", directorNamePartsList[3]);
comm.ExecuteNonQuery();
director_id = comm.LastInsertedId;
}
...and then assign it to the movies_main Table like so:
if (!alreadyExists)
{
comm.Parameters.Clear();
comm.CommandText = "INSERT INTO Movies_Main " +
"(movie_title, mpaa_rating, imdb_rating, movie_length, director_id,
screenwriter_id, year_released) " +
"VALUES " +
"(#movie_title, #mpaa_rating, #imdb_rating, #movie_length, #director_id,
#screenwriter_id, #year_released)";
comm.Parameters.AddWithValue("#movie_title", title);
comm.Parameters.AddWithValue("#mpaa_rating", mpaa_rating);
comm.Parameters.AddWithValue("#imdb_rating", Math.Round(imdb_rating, 1));
comm.Parameters.AddWithValue("#movie_length", movie_length);
comm.Parameters.AddWithValue("#director_id", director_id);
comm.Parameters.AddWithValue("#screenwriter_id", screenwriter_id);
comm.Parameters.AddWithValue("#year_released", year_released);
comm.ExecuteNonQuery();
movie_id = comm.LastInsertedId;
}
Yet the value assigned to the movies_main Table for director_id is always 0!
Why is LastInsertId (apparently) returning 0, and how can I get it to actually return the value its name claims it does? Will I have to resort to a "SELECT MAX(director_id)" query to actually get the value?
NOTE: The movie_id code does work! I get a non-zero value when assigning the result of the call to LastInsertedId to the movie_id variable, and it is added to other tables just fine. This code works as expected:
foreach (var gen_desc in genreList)
{
long genreID = Convert.ToInt32(GetGenreIDForDescription(gen_desc));
alreadyExists = PairAlreadyExistsInMoviesGenresM2Mtable(
movie_id, genreID);
if (!alreadyExists)
{
comm.Parameters.Clear();
comm.CommandText = "INSERT INTO Movies_Genres " +
"(movie_id, genre_id) " +
"VALUES " +
"(#movie_id, #genre_id)";
comm.Parameters.AddWithValue("#movie_id", movie_id);
comm.Parameters.AddWithValue("#genre_id", genreID);
comm.ExecuteNonQuery();
}
}
An alternative way to LastInsertedId property from the MySqlCommand is the native MySql function LAST_INSERT_ID. We can call this function and get its return value adding a simple SELECT statement to your current command text. MySql supports batch statements and so, with a single server call we could execute more than one single command text.
if (!alreadyExists)
{
comm.Parameters.Clear();
comm.CommandText = "INSERT INTO Directors " +
"(first_name, middle_name, last_name, suffix) " +
"VALUES " +
"(#first_name, #middle_name, #last_name, #suffix); " + // semicolon to close the first statement
"SELECT LAST_INSERT_ID()";
comm.Parameters.AddWithValue("#first_name", directorNamePartsList[0]);
comm.Parameters.AddWithValue("#middle_name", directorNamePartsList[1]);
comm.Parameters.AddWithValue("#last_name", directorNamePartsList[2]);
comm.Parameters.AddWithValue("#suffix", directorNamePartsList[3]);
director_id = Convert.ToInt64(comm.ExecuteScalar());
}
Note that we can now use ExecuteScalar because we get back just one record with a single column.
Let me say however that I have tried to reproduce your problem with LastInsertedId. I have recreated your table and written a simple script in LinqPad trying to insert some fixed data in that table.
I have no problem with LastInsertedId property and I get the correct value. I have read that if you have more threads that are concurrently inserting records you could get some problems with that property but I have no proof of any kind of misbehaving

SQL query execution order error

Starting to learn sql and having trouble with my query. I have - 2 tables calendar and activities and FK table DateActivities. Got 2 simple lists calendar with dates and activities. I want to be able with a button click to enter new activity through text box on selected date. But when I do that I get error on a query. Thanks for your help.
private void btnAddToDate_Click(object sender, EventArgs e)
{
string query = "DECLARE #ActivitiesId TABLE (Id INT) " +
"INSERT INTO Activities (Name) " +
"OUTPUT INSERTED.ID INTO #ActivitiesId Id(Id) " +
"VALUES (#ActivitiesName) " +
"INSERT INTO DateActivities VALUES (#CalendarId, #ActivitiesId)";
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
{
connection.Open();
command.Parameters.AddWithValue("#ActivitiesName", textDate.Text);
command.Parameters.AddWithValue("#CalendarId", listCalendar.SelectedValue);
command.ExecuteNonQuery();
}
FillCalendar();
FillActivities();
}
You are trying to execute multiple statement and thus need to separate them with ; as line terminator like below else it's treated as single statement to execute. If you just copy/paste the statement block in SSMS you will get the same error.
"DECLARE #ActivitiesId TABLE (Id INT); " +
"INSERT INTO Activities (Name) " +
"OUTPUT INSERTED.ID INTO #ActivitiesId Id(Id) " +
"VALUES (#ActivitiesName); " +
"INSERT INTO DateActivities VALUES (#CalendarId, #ActivitiesId)"
You should better pull this off to a stored procedure instead running as adhoc query.
You are inserting whole table in the column value of DateActivities which is obviously wrong and will fail, you need to use another variable to hold the ActivityId and then insert it next, see below:
"DECLARE #ActivitiesId TABLE (Id INT)
DECLARE #ActivityId INT " +
"INSERT INTO Activities (Name) " +
"OUTPUT INSERTED.ID INTO #ActivitiesId Id(Id) " +
"VALUES (#ActivitiesName) " +
"SELECT #ActivityId = Id from #ActivitiesId"
"INSERT INTO DateActivities VALUES (#CalendarId, #ActivityId)";

C# Alter Table and Add a column programmatically ASP.Net & SQL Server

I have been trying to add a column programmatically in ASP.NET to modify the tables in SQL Server.
Please see the following code:
string suppliernotxt = supplieridlist[1].ToString();
//SqlCommand cmd2 = new SqlCommand("ALTER TABLE [ProductNormalDB] ADD suppliernotxt nvarchar(20) NULL", con);
SqlCommand cmd2 = new SqlCommand("ALTER TABLE ProductNormalDB ADD #supplierlist nvarchar(20) NULL", con);
cmd2.Parameters.AddWithValue("#supplierlist", suppliernotxt);
//cmd2.Parameters.AddWithValue("#supplierlist", suppliernotxt.ToString());
//cmd2.Parameters["#supplierlist"].Value = supplieridlist[x];
cmd2.ExecuteNonQuery();
supplieridlist is an array that acquires all the column names to add into the SQL Server database. For some reason the parametrized method is not working and shows the following error:
Incorrect syntax near '#supplierlist'.
The basic idea is to have a user select from a check box the name of the suppliers, based on the selected number of suppliers the array will create the supplier names for ex. if we selected 3 suppliers, the array will save "Supplier1", "Supplier2", "Supplier3" and then the SqlCommand is supposed to alter the table and add the new columns.
You cannot use parameters to express the name of columns.
Parameters could only be used to express values for WHERE clause or for INSERT or UPDATE statements.
You could use string concatenation for your query text, passing the string value to a stored procedure or use some form of dynamic sql.
Please be very carefull with these kind of approaches because if you don't keep absolute control on the values passed to your code you will be exposed to Sql Injection.
Adding as an example of Dynamic SQL execution, but still vulnerable to SQL Injection
string suppliernotxt = supplieridlist[1].ToString();
string execSQL = "DECLARE #sup nvarchar(15); " +
"SET #sup = '" + suppliernotxt + "'; " +
"EXEC ('ALTER TABLE ProductNormalDB ADD ' + #sup + ' nvarchar(20) NULL')"
SqlCommand cmd2 = new SqlCommand(execSQL, con);
cmd2.ExecuteNonQuery();
As you can see, even with Dynamic SQL there is nothing that prevent an SQL Injection attack passing via the suppliernotxt variable
EDIT As explained in the comments below from #RBarryYoung, a good improvement on the SQL Injection problem for this case of dynamic sql could be the usage of the QUOTENAME function to obtain an Unicode string with the required delimiters around the input string
string execSQL = "DECLARE #sup nvarchar(15); " +
"SET #sup = QUOTENAME('" + suppliernotxt + "'); " +
"EXEC ('ALTER TABLE ProductNormalDB ADD ' + #sup + ' nvarchar(20) NULL')"

Categories

Resources