SQL replace two records while cloning a row - c#

I have coded this snippet to clone a selected row in a table:
protected void Button4_Click(object sender, EventArgs e)
{
DateTime ucode = DateTime.Now;
string slctedProj = DropDownList1.SelectedItem.ToString();
string new_code = "PR" + ucode.ToString("ssmmHHddMM");
string query = #"INSERT INTO Projects (proj_id, proj_prod_id, proj_cust_id, proj_man_id,
proj_name, proj_date, proj_num_of_vehicles, proj_coach_vehicle,
proj_contract_value, proj_length, proj_width, proj_height, proj_passenger_seats,
proj_passenger_total, proj_type, proj_notes, uname, proj_brand, proj_systemvoltage,
proj_gauge, proj_service_speed)
SELECT proj_id, proj_prod_id, proj_cust_id, proj_man_id,
proj_name, proj_date, proj_num_of_vehicles, proj_coach_vehicle,
proj_contract_value, proj_length, proj_width, proj_height, proj_passenger_seats,
proj_passenger_total, proj_type, proj_notes, uname, proj_brand, proj_systemvoltage,
proj_gauge, proj_service_speed
FROM Projects WHERE proj_name =" + "'" + slctedProj + "'";
System.Windows.Forms.MessageBox.Show(query);
string getconnstring = ConfigurationManager.ConnectionStrings["stad_conn"].ConnectionString;
SqlConnection conn = new SqlConnection(getconnstring);
conn.Open();
SqlCommand cmd = new SqlCommand(query, conn);
cmd.ExecuteNonQuery();
conn.Close();
}
the code is working fine but I need to replace in the new row, "proj_id" with the string "new_code" and attach at the beginning of the "proj_name" something like "Cloned".
How can I do that?

First of all: Use parameters in your SQL command.
Heres the revised code, with parameters. Note that the Add method on the parameters is specifying both the data type as well as the length. It's better to specify these explicitly rather than let ADO.Net assume it knows what you want.
DateTime ucode = DateTime.Now;
string slctedProj = DropDownList1.SelectedItem.ToString();
string new_code = "PR" + ucode.ToString("ssmmHHddMM");
string new_projectName = "Some new name";
string query = #"INSERT INTO Projects (proj_id, proj_prod_id, proj_cust_id, proj_man_id,
proj_name, proj_date, proj_num_of_vehicles, proj_coach_vehicle,
proj_contract_value, proj_length, proj_width, proj_height, proj_passenger_seats,
proj_passenger_total, proj_type, proj_notes, uname, proj_brand, proj_systemvoltage,
proj_gauge, proj_service_speed)
SELECT #NewProjectID, proj_prod_id, proj_cust_id, proj_man_id,
#NewProjectName, proj_date, proj_num_of_vehicles, proj_coach_vehicle,
proj_contract_value, proj_length, proj_width, proj_height, proj_passenger_seats,
proj_passenger_total, proj_type, proj_notes, uname, proj_brand, proj_systemvoltage,
proj_gauge, proj_service_speed
FROM Projects WHERE proj_name = #SelectedProj";
System.Windows.Forms.MessageBox.Show(query);
string getconnstring = ConfigurationManager.ConnectionStrings["stad_conn"].ConnectionString;
SqlConnection conn = new SqlConnection(getconnstring);
conn.Open();
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add("#NewProjectID", SqlDbType.VarChar, 20).Value = new_code;
cmd.Parameters.Add("#NewProjectName", SqlDbType.VarChar, 20).Value = new_projectName;
cmd.Parameters.Add("#SelectedProj", SqlDbType.VarChar, 20).Value = slctedProj;
cmd.ExecuteNonQuery();
conn.Close();

This is not an answer. You could improve this design by keeping a reference to source / initial project using a FK (only for cloned projects) thus:
ALTER TABLE dbo.Projects
ADD source_proj_id INT NULL
REFERENCES dbo.Projects(proj_id);
GO
and you need to change also the insert statement thus:
string query = #"INSERT INTO Projects
(proj_id, source_proj_id, proj_prod_id, ...)
SELECT #NewProjectID, proj_id, proj_prod_id, ...
FROM Projects WHERE proj_name = #SelectedProj";

Related

passing columnname with a parameter SQLcommand

I've been googling something I dont really cant understand.
In short my problem is this;
When using this;
String sYear2 = "2020";
string query = #"Select decJan from Stats where intRecnum = (select intRecnum from Stats where intAr = #year)";
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);
The result is returning "111" (which is correct vaule of column decJan the year 2020.
But when trying this;
String sYear2 = "2020";
String sColumn2 = "decJan";
string query = #"Select " + #column + #" from tbFuGraddagar where intRecnum = (select intRecnum from tbfuGraddagar where intAr = #year)";
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);
cmd.Parameters.AddWithValue("#column", sColumn2);
I recieve "decJan" as result.
When googling all I have found that its not possible without dynamic SQL or that is bad design.
But I fail to understand what the diffrence is...all I want is to change the static code with a value similar to #year-parameter. the "interpretation" shouldn't care about the validation of SQL-syntax, it's just a matter och string-manipulation.
Or is it just me beeing a bad C#-coder?
Probably addwithvalue method is not valid for adding dynamic column names in select statements. I think you should use c# 8.0 feature, string interpolation to solve this problem.  You can add column names with string interpolation. Can you try this approach :
String sYear2 = "2020";
string deccan = "decJan";
string query = $(Select {decJan} from Stats where intRecnum = (select intRecnum from Stats where intAr = #year)
query = #query;
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);

How to get selected ID from SQL database using textBox and update information?

I am trying to update a databse entry under a specific id in my table when the users enter their ID number in a textBox.
At the moment it updates but updates all entries in my table except the entry containing the users ID number.
This is the code I am currently using:
private void Button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(#"Data Source=DEVELOPMENT\ACCESSCONTROL;Initial Catalog=ACCESSCONTROL;User ID=sa;Password=P#55w0rd123");
SqlCommand check_User_Name = new SqlCommand("SELECT Id FROM NewVisitor WHERE (IDNumber = #IDNumber)", con);
check_User_Name.Parameters.AddWithValue("#IDNumber", idNumber_TxtBox.Text);
con.Open();
int UserExist = (int)check_User_Name.ExecuteScalar();
if (UserExist > 0)
{
var connetionString = #"Data Source=DEVELOPMENT\ACCESSCONTROL;Initial Catalog=ACCESSCONTROL;User ID=sa;Password=P#55w0rd123";
var sql = "UPDATE NewVisitor SET PersonVisit = #PersonVisit, PurposeVisit = #PurposeVisit, Duration = #Duration, Disclaimer = #Disclaimer";
try
{
using (var connection = new SqlConnection(connetionString))
{
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#PersonVisit", SqlDbType.NVarChar).Value = personVisiting_TxtBox.Text;
command.Parameters.Add("#PurposeVisit", SqlDbType.NVarChar).Value = purposeOfVisit_CMBox.SelectedItem;
command.Parameters.Add("#Duration", SqlDbType.Date).Value = duration_dateTimePicker1.Value.Date;
command.Parameters.Add("#Disclaimer", SqlDbType.NVarChar).Value = disclaimer_CHKBox.Checked;
connection.Open();
command.ExecuteNonQuery();
}
}
}
The whole table has many more fields but would like to just update the above fields within that specific ID.
Thanks
You forgot the WHERE clause on the UPDATE statement, telling it specifically which records to update. It sounds like you just want to add the exact same WHERE clause that you have on your SELECT:
var sql = "UPDATE NewVisitor SET PersonVisit = #PersonVisit, PurposeVisit = #PurposeVisit, Duration = #Duration, Disclaimer = #Disclaimer WHERE (IDNumber = #IDNumber)";
And don't forget to add the paramter for it:
command.Parameters.Add("#IDNumber", SqlDbType.Int).Value = idNumber_TxtBox.Text;
You may need to convert the input value to an integer first, I'm not 100% certain (it's been a while since I've had to use ADO.NET directly). Something like this:
if (!int.TryParse(idNumber_TxtBox.Text, out var idNumber))
{
// input wasn't an integer, handle the error
}
command.Parameters.Add("#IDNumber", SqlDbType.Int).Value = idNumber;

SQL INSERT an ID of freshly inserted row

im writing a library database program. It can insert books, but I have a problem in making a reference between book and a person which rents it. I can't get a last inserted id from a rents table to put it to the compilation table to assign book to a person who rents it. I've tried SCOPE_IDENTITY() but it doesn't works for me. Here's the code:
private void addRentButton_Click(object sender, EventArgs e) {
elibrary f1 = new elibrary();
string query = "INSERT INTO rents VALUES (#renterName, #rentStartDate, #rentEndDate)";
using(f1.Connection = new SqlConnection(f1.connectionString))
using(SqlCommand command = new SqlCommand(query, f1.Connection)) {
f1.Connection.Open();
command.Parameters.AddWithValue("#renterName", rentNameBox.Text);
command.Parameters.AddWithValue("#rentStartDate", DateTime.Now);
command.Parameters.AddWithValue("#rentEndDate", rentEndDatePicker.Value);
command.ExecuteScalar();
}
rentEndDatePicker.Value = DateTime.Now;
string Compilationquery =" INSERT INTO compilation VALUES (#bookId, SELECT SCOPE_IDENTITY())";
using(f1.Connection = new SqlConnection(f1.connectionString))
using(SqlCommand command = new SqlCommand(Compilationquery, f1.Connection)) {
f1.Connection.Open();
command.Parameters.AddWithValue("#bookId", f1.listBook.SelectedValue);
command.ExecuteScalar();
Actually, you are not retrieving the last inserted ID value from the first query, since the SCOPE_IDENTITY() is wrongly placed and you are not assigning the ExecuteScalar() return value anywhere:
String query = "INSERT INTO rents VALUES (#renterName, #rentStartDate, #rentEndDate); SELECT CONVERT(INT, SCOPE_IDENTITY())"; // "SELECT CAST(SCOPE_IDENTITY() AS INT)" can also be an option
Int32 lastId = 0;
using (f1.Connection = new SqlConnection(f1.connectionString))
using (SqlCommand command = new SqlCommand(query, f1.Connection))
{
f1.Connection.Open();
command.Parameters.AddWithValue("#renterName", rentNameBox.Text);
command.Parameters.AddWithValue("#rentStartDate", DateTime.Now);
command.Parameters.AddWithValue("#rentEndDate", rentEndDatePicker.Value);
lastId = (Int32)command.ExecuteScalar();
}
Once this is done, you can proceed with the second query as follows:
String compilationQuery = "INSERT INTO compilation VALUES (#bookId, #rentId)";
using (f1.Connection = new SqlConnection(f1.connectionString))
using (SqlCommand command = new SqlCommand(compilationQuery, f1.Connection))
{
f1.Connection.Open();
command.Parameters.AddWithValue("#bookId", f1.listBook.SelectedValue);
command.Parameters.AddWithValue("#rentId", lastId);
// ...
You have disposed the command so SCOPE_IDENTITY() is gone. There is no reason to dispose of the commmand twice.
using(SqlCommand command = new SqlCommand(query, f1.Connection))
{
f1.Connection.Open();
command.Parameters.AddWithValue("#renterName", rentNameBox.Text);
command.Parameters.AddWithValue("#rentStartDate", DateTime.Now);
command.Parameters.AddWithValue("#rentEndDate", rentEndDatePicker.Value);
command.ExecuteScalar();
int id = (Int32)command.ExecuteScalar();
command.Parameters.Clear();
Compilationquery = "INSERT INTO compilation VALUES (#bookId, #id)";
command.CommandText = Compilationquery;
command.Parameters.AddWithValue("#bookId", f1.listBook.SelectedValue);
command.Parameters.AddWithValue("#id", id);
command.ExecuteScalar();
}

Parsing varchar as int for inserting values into the database

I have to add 4 values into my table:#SNTeacher,#name,#pwd and #courseID.The #courseID is a FK in my RegisterTeacher table and a PK I Courses table along with another attribute-#coursename.
My problem is that when I want to insert the values into the table, I get an error at #courseID saying that it can't convert from varchar to int although my #courseID is an int.
My #courseID and #coursename are binded to comboBoxcourse1 and it has DisplayMember-coursename and ValueMember=courseID.My opinion is that it makes the confusion between the two of them since #coursename is a varchar, but then again I don't see the logic since I'm adding the #courseID parameter to the table RegisterTeacher.
I also tried to parse it in 3 different ways that I have also found here, on Stack Overflow but still I get errors saying that the input string was not in a correct format.
This is my code with the error and in is also the last method I used to try to parse the value:
private void btnRegister_Click(object sender, EventArgs e)
{
string connString = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User\source\repos\VIAUniversityCollegeAttendanceApp\VIAUniversityCollegeAttendanceApp\DatabaseAttendanceStudents.mdf;Integrated Security=True;Connect Timeout=30";
SqlConnection con = new SqlConnection(connString);
con.Open();
SqlCommand cmd = new SqlCommand("Insert into RegisterTeacher values(#SNTeacher,#name,#pwd,#courseID) ", con);
cmd.Parameters.AddWithValue("#SNTeacher", textBoxSN.Text);
cmd.Parameters.AddWithValue("#name",textBoxName.Text);
cmd.Parameters.AddWithValue("#pwd", textBoxpwd.Text);
string nvarchar = "#courseID";
var one = int.Parse(nvarchar);
var bone = int.TryParse(nvarchar, out one);
cmd.Parameters.AddWithValue("#courseID", comboBoxcourse1.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Registration succesfull!");
}
This should work for you:
int parameterValue;
SqlParameter parameter = new SqlParameter("#courseID", SqlDbType.Int);
if(Int32.TryParse(comboBoxcourse1.SelectedValue?.ToString() ?? String.Empty, out parameterValue))
{
parameter.Value = parameterValue;
}
else
{
parameter.Value = DBNull.Value;
}
cmd.Parameters.Add(parameter);

Dropdown list selected index returns null

I have a web page that generates an incident report in a database. The incident report is tied to a car table using car ID.
When I click the submit button I get an error in the DAL that reads "Additional information: Cannot insert the value NULL into column 'CarID', table 'RideXpress.dbo.IncidentReport'; column does not allow nulls. INSERT fails."
The relevant aspx code is as follows
<asp:DropDownList ID="DD1" runat="server" CssClass="form-control" AutoPostBack="true" ></asp:DropDownList>
The relevant code behind file follows
string connectionString = ConfigurationManager.ConnectionStrings["RideXpressConnectionString"].ToString();
ReportBLL ReportBL = new ReportBLL(connectionString);
ReportViewModel report = new ReportViewModel();
int ID = DD1.SelectedIndex;
report.CarID = ID;
report.DateOfIncident = Convert.ToDateTime(Date.Text);
report.ReportName = Name.Text;
report.ReportDescription = Description.Text;
report.DateOfReport = DateTime.Today;
ReportBL.AddReport(report);
Response.Redirect("~/Reports.aspx");
and the DAL, where the error is raised follows
public int AddReport(ReportViewModel add)
{
string sqlQuery = "INSERT INTO IncidentReport(DateOfIncident, ReportName, ReportDescription, DateOfReport)" +
"Values (#DateOfIncident, #ReportName, #ReportDescription, #DateOfReport)";
using (SqlConnection con = new SqlConnection(_connectionString))
using (SqlCommand cmd = new SqlCommand (sqlQuery, con))
{
con.Open();
cmd.Parameters.Add("#ReportID", SqlDbType.Int).Value = add.ReportID;
cmd.Parameters.Add("#CarID", SqlDbType.Int).Value = add.CarID;
cmd.Parameters.Add("#DateOfIncident", SqlDbType.DateTime).Value = add.DateOfIncident;
cmd.Parameters.Add("#ReportName", SqlDbType.VarChar).Value = add.ReportName;
cmd.Parameters.Add("#ReportDescription", SqlDbType.VarChar).Value = add.ReportDescription;
cmd.Parameters.Add("#DateOfReport", SqlDbType.DateTime).Value = add.DateOfReport;
return cmd.ExecuteNonQuery();
}
}
Any help would be very much appreciated.
Change the query to
string sqlQuery = "INSERT INTO IncidentReport(CarID,DateOfIncident, ReportName, ReportDescription, DateOfReport)" +
"Values (#CarID,#DateOfIncident, #ReportName, #ReportDescription, #DateOfReport)";
Also ReportId is not in the query so it would not get set, either add it to the query like I did carID above or if it is identity auto increment don't set it at all.

Categories