Retrieve mssql primary key from query? - sql-server

In C# Visual Studio Express Windows Forms:
How do I retrieve the primary key of a just executed insert query.
Here is my con+query code:
SqlConnection con = new SqlConnection(...);
SqlCommand command = con.CreateCommand();
command.CommandText = "INSERT INTO bestillinger (ha) VALUES (#ha);
command.Parameters.AddWithValue("#ha", listBox1.SelectedItem.ToString());
con.Open();
command.ExecuteNonQuery();
con.Close();

With a manual Close(), you risk leaking a connection if the code that uses it throws an exception. So please use using instead.
Assuming your PK is an identity column, the new value is most easily retrieved with scope_identity():
using (var con = new SqlConnection(...))
{
con.Open();
var command = con.CreateCommand();
command.CommandText = #"
INSERT INTO bestillinger (ha) VALUES (#ha);
select scope_identity();";
command.Parameters.AddWithValue("#ha", listBox1.SelectedItem.ToString());
var newPk = (long) command.ExecuteScalar();
}

As #Andomar said in his answer, ensure you properly close the connection.
Another way to return the value of the newly inserted identity field would be:
using (var con = new SqlConnection(...))
{
con.Open();
var command = con.CreateCommand();
command.CommandText = #"
INSERT INTO bestillinger (ha) OUTPUT inserted.[ID] VALUES (#ha);";
command.Parameters.AddWithValue("#ha", listBox1.SelectedItem.ToString());
var newPk = (long) command.ExecuteScalar();
}
[ID] would be replaced with the name of the identity field (or any field, or fields) that you want.

Related

Save list of Arabic strings in database

I have a c# program. I have list of string. The elements of that list in Arabic. When I try to save the elements of list in database I see symbols "??????"
Here my code
List<string> _names = new List<string>()
{
"ذهب",
"قال",
"تعال",
"متى",
"البرمجة",
"احمد"
};
SqlConnection connection = new SqlConnection("Server=DESKTOP-JRS3DQ4; DataBase=Library_DB; Integrated Security=true");
connection.Open();
for (int index = 0; index < _names.Count; index++)
{
SqlCommand command = new SqlCommand("INSERT INTO tbl_names (id,name) VALUES ('" + index + "', '" + _names[index] + "')", connection);
command.ExecuteNonQuery();
}
connection.Close();
How I can solve this problem please?
Most likely, your problem is coming from inserting strings (as varchar) instead of NVarchar.
Your code will work more-reliably, safer & faster if you define a parameterized query and parameters before you run your loop:
List<string> _names = new List<string>()
{
"ذهب",
"قال",
"تعال",
"متى",
"البرمجة",
"احمد"
};
SqlConnection connection = new SqlConnection("Server=DESKTOP-JRS3DQ4; DataBase=Library_DB; Integrated Security=true");
connection.Open();
SqlCommand command = new SqlCommand("INSERT INTO tbl_names (id,name) VALUES (#Id, #Name)", connection);
command.Parameters.Add("#Id", SqlDbType.Int);
command.Parameters.Add("#Name", SqlDbType.NVarChar, 20); //size and type must match your DB
for (int index = 0; index < _names.Count; index++)
{
command.Parameters["#Id"].Value = index;
command.Parameters["#Name"].Value = _names[index];
command.ExecuteNonQuery();
}
connection.Close();
One last note: This will not help unless your DB has the Name column defined as a NVarChar.

Linq To Sql Conversation In Wcf Service

Can you please provide an answer following sql query to linq . I have some knowledge about linq but i am confused about sql reader object ..
public AccountBalanceRequest AccountBalanceCheek(AccountBalanceRequest accountNumber)
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
var cmd = new SqlCommand("SELECT Account_Type,Account_Fees,Account_Balance,Over_Draft_Limit FROM Current_Account_Details WHERE Account_Number = '" + accountNumber.Account_Number + "'", conn);
cmd.CommandType = CommandType.Text;
var reader = cmd.ExecuteReader();
//read the result of the execute command.
while (reader.Read())
{
//assuming that your property is the same as your table schema. refer to your table schema Current_Account_Details
accountNumber.Account_Type = reader["Account_Type"].ToString();
accountNumber.Account_Fee = reader["Account_Fees"].ToString();
accountNumber.Account_Balance = reader["Account_Balance"].ToString();
accountNumber.Over_Draft_Limit = reader["Over_Draft_Limit"].ToString();
}
return accountNumber;
}
}
First you have to have DbContext which you must instantiate in using(usual practice):
using (DbContext db = new DbContext())
{
var results = (from ad in db.Current_Account_Details
where ad.Account_Number == accountNumber.Account_Number
select ad).ToList();
}
Make sure you have created the object data model from database.
I do not get the other part of your post but this would be the general idea of how to write Linq2Entities queries.

Code Generation of an Upsert / Merge for SQL Server - C#/.NET

What is the best way to generate an "UPSERT" Merge statement for SQL Server? I'm looking for a way to just put in a SQL Server connection string and then point a piece of code at a single SQL Server table.
Is it to crawl INFORMATION_SCHEMA.COLUMNS and INFORMATION_SCHEMA.TABLES for the metadata and write a small console app? other suggestions?
I'd like to be able to copy and paste the resulting code into a "const string sql" variable to then use with something like Dapper.
The fastest way to upsert in SQL Server in C# is to bulk insert into a temp table and issue a merge from there to the production table.
var tmpTable =
"create table #myTable (a as int, b as nvarchar(200)";
var conString = "my_connection_string";
using (var con = new SqlConnection(conString))
{
con.Open();
//Create Temp Table
var cmd = new SqlCommand(tmpTable, con);
cmd.ExecuteNonQuery();
//Build Data Set
var dt = new DataTable();
dt.Columns.Add(new DataColumn("A", typeof(int)));
dt.Columns.Add(new DataColumn("B", typeof(string)));
foreach (var myDataRow in myData)
{
var row = dt.NewRow();
row["A"] = myDataRow.A;
row["B"] = myDataRow.B;
dt.Rows.Add(row);
}
//Write to temp table
using (var bulk = new SqlBulkCopy(con))
{
bulk.BulkCopyTimeout = 0;
bulk.DestinationTableName = "#myTable";
bulk.WriteToServer(dt);
}
//Do the upsert
var mergeSql = "merge into myData as Target " +
"using #myTable as Source " +
"on " +
"Target.A=Source.A " +
"and Target.B = Source.B " +
"when matched then " +
"update set Target.A=Source.A, Target.B = Source.B, " +
"when not matched then " +
"insert (A,B) values (Source.A,Source.B);";
cmd.CommandTimeout = 0;
cmd.CommandText = mergeSql;
cmd.ExecuteNonQuery();
//Clean up the temp table
cmd.CommandText = "drop table #myTable";
cmd.ExecuteNonQuery();
}
}
I've tested several ways and this is the fastest I have came across. I use it in a production environment for inserting millions of rows daily without issue.

How to update multiple rows / How to perform Operation on multiple records (C#, SQL Server)

I have a database table name Players (ID, Name, Scores).
here is my code to binding it with database
private void playerList(int team1_ID)
{
try
{
if (con.State == ConnectionState.Closed)
{
con.Open();
}
string query = "SELECT player_name AS [Player Name] , Score AS [Score] FROM Players WHERE Team_id= " + team1_ID;
SqlCommand cmd = new SqlCommand(query, con);
adapter = new SqlDataAdapter(cmd);
adapter.Fill(ds, "Players");
dGridPlayers.DataSource = ds.Tables["Players"];
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
con.Close();
}
}
This code is working fine. It returns a list of 11 players and their Scores.
Now I want to perform some arithmetic operation on Score of each player and want to store back (update ) to the database table. Please tell how to do this.
(I don't want to hit SQL every time to update for each player's score. I want to update every players scores in one go after finishing the operations.)
You need to define
an UPDATE SQL statement to do your update
call that UPDATE from your C# code
use parametrized query to avoid SQL injection and bad performance !!
put your usage of SqlConnection and SqlCommand into using() {....} blocks to ensure proper disposal
Something like this:
// define your UPDATE query
string updateQuery = "UPDATE dbo.Players SET Score = Score + #Value WHERE Team_id = #TeamID";
// two nested "using" blocks for conenction and command
using (SqlConnection conn = new SqlConnection(.....))
using (SqlCommand cmd = new SqlCommand(updateQuery, con))
{
// define the parameters and provide values
cmd.Parameters.Add("#Value", SqlDbType.Int).Value = someValue;
cmd.Parameters.Add("#TeamID", SqlDbType.Int).Value = teamID;
// open connection, execute the UPDATE, close connection
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
To update records just apply something similar to what marc_s suggested.
If you want to update all records at once keep primary keys and new values in a structure like this
Dictionary<int, int> values = new Dictionary<int, int>();
Key for the dictionary will hold the primary key for the table and value will be the new score for that record.
When you want to update the database just loop through all of these inside of the using SQLCommand block marc_s showed
using (SqlCommand cmd = new SqlCommand(updateQuery, con))
{
// open connection, execute the UPDATE, close connection
conn.Open();
foreach (KeyValuePair<int, int> row in values)
{
cmd.Parameters.Clear();
cmd.Parameters.Add("#PK", SqlDbType.Int).Value = row.Key;
cmd.Parameters.Add("#Score", SqlDbType.Int).Value = row.Value;
cmd.ExecuteNonQuery();
}
conn.Close();
}

Inserting a single row with large number of columns in SQL Server

I have a huge form that has around 110 fields columns (single row) that need to be saved in a database.
What is the best approach to insert these many columns into the database using ADO.NET?
I don't think I should be using an insert statement like this, since the query would be very large due to the number of fields.
conn.Open();
string insertString = #"
insert into Categories (CategoryName, Description)
values ('Miscellaneous', 'Whatever doesn''t fit elsewhere')";
SqlCommand cmd = new SqlCommand(insertString, conn);
cmd.ExecuteNonQuery();
I think of dumping the data into temp file and then adding them into a datatable and then inserting them into database using SqlBulkCopy.
Is there a better approach? How would you handle this situation?
I am afraid there isn't a good shortcut for inserting this number of columns, but using parameters will likely save some debugging time. By using parameters you do not need to worry about things likes apostrophes in strings and type conversions. Here's a sample:
public static void TryThis()
{
try
{
using (SqlConnection con = new SqlConnection())
{
con.ConnectionString = "YourConnectionString";
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO Categories (CategoryName, Description) VALUES (#CategoryName, #Description)";
cmd.Parameters.AddWithValue("CategoryName", "Miscellaneous");
cmd.Parameters.AddWithValue("Description", "Whatever doesn't fit elsewhere");
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

Resources