How to store the value of the PolicyID returned from database in an integer variable in C#?
I am using SQL server 2005.
System.Data.SqlClient.SqlConnection dataConnection = new SqlConnection();
dataConnection.ConnectionString =
#"Data Source=JAGMIT-PC\SQLEXPRESS;Initial Catalog=SumooHAgentDB;Integrated Security=True";
System.Data.SqlClient.SqlCommand dataCommand = new SqlCommand();
dataCommand.Connection = dataConnection;
dataCommand.CommandText = ("select PolicyID from Policies where PolicyID=(select max(PolicyID) from Policies)");
dataConnection.Open();
dataCommand.ExecuteNonQuery();
dataConnection.Close();
Please suggest.
Thanks.
Use the SqlCommand.ExecuteScalar method, like this:
command.CommandText = #"select max(PolicyID) from Policies";
int maxPolicyId = (int)command.ExecuteScalar();
Also, if you're doing this to insert a new Policy row with a unique ID, you must not do it like this, because it's entirely possible that a different Policies row will be inserted between the select and the insert.
Instead, use an IDENTITY column or a UNIQUEIDENTIFIER column.
EDIT: To use this in your code, do this:
int maxId;
using (SqlConnection dataConnection = new SqlConnection(#"Data Source=JAGMIT-PC\SQLEXPRESS;Initial Catalog=SumooHAgentDB;Integrated Security=True"))
using (SqlCommand dataCommand =
new SqlCommand("select max(PolicyID) from Policies", dataConnection)) {
dataConnection.Open();
maxId = Convert.ToInt32(dataCommand.ExecuteScalar());
}
DECLARE #id INTEGER
SELECT #id=PolicyID FROM ...
Did you just insert a new record into that policy table and now you want the ID given?
Then instead of a max(), use
SELECT SCOPY_IDENTITY()
to get the value that was assigned to your record, not to a record that happened to be inserted moments later.
You can also use SELECT IDENT_CURRENT('Policies') to get the value that was created for your record. To learn more about the differences between SCOPE_IDENTITY() AND IDENT_CURRENT('tablename'), check out this link.
Related
Is there a way to access a table that I have added to the default ASPNETDB.MDF database that is given to you when you create a new web page in asp.net 4.0. I have added a table called BuilderTable with 5 columns. Also I need it to increment ID on its own. I have set the is identity option to yes and the identity increment to 1 so how can I get it to work without sending it a value for the ID column in my code behind. Here is said code in c#:(I have it within a switch statement so dont mind the case 1)
case "1":
if (Roles.IsUserInRole(usr.UserName, "Builder") == false)//if the user is not already in the builder role then add them
{
Roles.AddUserToRole(usr.UserName, "Builder");//here we add the user into the builder role
string connection = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
SqlConnection conn = null;
conn = new SqlConnection(connection);
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
int nothing = 0;
string query = String.Format("INSERT INTO 'BuilderTable' VALUES('{0}', '{1}', '{2}', '{3}', '{4}')", nothing, p.fName, p.lName, p.Address, usr.Email);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
cmd.ExecuteNonQuery();
}
}
break;
This code results in the error:
Incorrect syntax near 'BuilderTable'
Thanks in advance!
EDIT
Thought I should clarify I have this declared elsewhere in the code
string userName = Request.QueryString["user"];
MembershipUser usr = Membership.GetUser(userName);
ProfileCommon p = Profile.GetProfile(usr.UserName);
You need to take away the single quotes from around the table name. I.e. 'BuilderTable'
(You should be using parametrized queries. Look up "Sql Injection Attacks".)
Your identity error is due to you trying to insert values into the identity field. You should insert values by specifying the fields.
INSERT INTO BLAH (Fields,,,,) VALUES(Values,,,,,)
I need to retrieve a value from a field in database. I have the used following code. but the value checkOrderId (which I need) shows the SQL string instead of the value from database. I don't know why it is doing so. Could somebody help me please?
string connectionString = "Data Source = xxyyzz;Initial Catalog = xyz; Integrated Security = True";
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
string tableName = "[GIS].[SecondaryTraffic].[PotentialBackHauls]";
string checkOrderId = "Select TOP 1 OrderID From" + tableName + "ORDER BY InsertDate DESC";
SqlCommand cmd = new SqlCommand(checkOrderId, connection);
//cmd.ExecuteNonQuery();
OpenPop.Pop3.Pop3Client popConn = new OpenPop.Pop3.Pop3Client();
if (orderIdentity == checkOrderId)
{
popConn.DeleteMessage(messageNumber);
}
connection.Close();
I am new and dont have reputation to answer my question immediately. With everybody's help, i got this one solved...Great help, thanx everybody...following is my code.
string connectionString = "Data Source = EAEDEV;Initial Catalog = GIS; Integrated Security = True";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string tableName = "[GIS].[SecondaryTraffic].[PotentialBackHauls]";
string checkOrderId = "Select TOP 1 OrderID From " + tableName + " ORDER BY InsertDate DESC";
SqlCommand cmd = new SqlCommand(checkOrderId, connection);
string valueReturned = (string)cmd.ExecuteScalar();
OpenPop.Pop3.Pop3Client popConn = new OpenPop.Pop3.Pop3Client();
if (orderIdentity == valueReturned)
{
popConn.DeleteMessage(messageNumber);
}
connection.Close();
}
You need to execute the query and check the results, here you are just comparing a string with the query SQL.
Please see here
http://www.csharp-station.com/Tutorial/AdoDotNet/lesson03
for a tutorial.
Your expectation of the result being set into checkOrderId is incorrect. In this instance checkOrderId is just the query to execute and not the actual result.
You need to read the value back from executing the command:
using (var connection = new SqlConnection(connectionString))
using (var comm = new SqlCommand("Select TOP 1 OrderID From [GIS].[SecondaryTraffic].[PotentialBackHauls] ORDER BY InsertDate DESC", connection))
{
connection.Open();
object result = comm.ExecuteScalar(); // This is the key bit you were missing.
if (result != null)
{
// You can cast result to something useful
int orderId = (int)result;
}
} // Both comm and connection will have Dispose called on them here, no need to Close manually.
ExecuteScalar returns the value in the first cell (ie, column 1 row 1) as an object that you can cast to a better type (depending on what type it was in the result-set schema).
If you need to read multiple values, you need to look at ExecuteReader.
There are also other ways of doing this using output parameters, but that would pollute the point of the answer.
You can add space to your query
"Select TOP 1 OrderID From " + tableName + " ORDER BY InsertDate DESC";
Nota : I suggest you to use AddWithValue method with your parameter
string checkOrderId = "Select TOP 1 OrderID From #tableName ORDER BY InsertDate DESC";
SqlCommand cmd = new SqlCommand(checkOrderId, connection);
cmd.Parameters.AddWithValue("#tableName", tableName );
Link : http://msdn.microsoft.com/fr-fr/library/system.data.sqlclient.sqlparametercollection.addwithvalue.aspx
You don't actually run your command anywhere. Instead of the commented-out cmd.ExecuteNonQuery, you should look into the ExecuteScalar method, which allows you to read back a single result value from a query - which is what your query returns.
Add
int i = (Int32) cmd.ExecuteScalar();
right after
SqlCommand cmd = new SqlCommand(checkOrderId, connection);
then the variable i will contain the order id
No, this is not correct. You are comparing the variable orderId to your query string. I doubt that's what you want to do. I imagine you'd be better off calling cmd.ExecuteScalar() to retrieve the actual OrderID value. As noted by other answers, your query string is missing a space. But most importantly, it is bad practice to construct SQL queries in code. Although I can't see a security issue with this code, if you continue to use this method you will probably write code that is vulnerable to SQL injection. I recommend you learn to either use parameters or LINQ to build your queries.
I'm trying to solve why my code isn't working. Tip is preciated. I'm also wondering, when this works, will the Primary key, in this case, the ID columns also reset and start all over from 1?
connection = new SqlConnection(connectionString);
connection.Open();
sql = "DELETE * From Guests";
sqlCommand = new SqlCommand(sql, connection);
sqlCommand.EndExecuteNonQuery();
connection.Close();
You don't need the asterisk
DELETE FROM Guests
To reset the primary key, use
TRUNCATE TABLE Guests
And you want
sqlCommand.ExecuteNonQuery();
not EndExecuteNonQuery
You don't need the "*". The correct syntax for a delete statement is:
delete from Guests
You should also get into the habit of using "using" for disposable types, like SqlConnection and SqlCommand. Like this:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql = "DELETE From Guests";
using (SqlCommand sqlCommand = new SqlCommand(sql, connection))
{
sqlCommand.ExecuteNonQuery();
}
}
public static void CreateSocialGroup(string FBUID)
{
string query = "INSERT INTO SocialGroup (created_by_fbuid) VALUES (#FBUID); SELECT ##IDENTITY AS LastID";
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#FBUID", FBUID);
connection.Open();
command.ExecuteNonQuery();
}
}
Is this the right way to do it? And how do i get LastID in to a variable? Thanks
OUTPUT clause?
string query = "INSERT INTO SocialGroup (created_by_fbuid)
OUTPUT INSERTED.IDCol --use real column here
VALUES (#FBUID)";
...
int lastId = (int)command.ExecuteScalar();
You can use ExecuteScalar to get the last value from a Sqlcommand.
The scope_identity() function is safer than ##identity.
If your server supports the OUTPUT clause you could try it with this one:
public static void CreateSocialGroup(string FBUID)
{
string query = "INSERT INTO SocialGroup (created_by_fbuid) OUTPUT INSERTED.IDENTITYCOL VALUES (#FBUID)";
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#FBUID", FBUID);
connection.Open();
var _id = command.ExecuteScalar();
}
}
Personally, I would re-write your code to use Parameters. You could either use an InputOutput parameter or an Output Parameter. However, using a Return Value in your SQL would also work.
Full examples on this can be found on MSDN.
I would also use Scope_Identity() rather than ##Identity this will ensure that you will reveice the ID that relates to the current transaction. Details on Scope_Identity can be found here.
U can try ExecuteScalar for getting the LastID value.
I'd recommend to use a stored procedure to do this. You can give it an OUTPUT parameter which you can use to return the id value back to your app.
cmd = new SqlCommand("Insert into table values (1,2,3); SELECT SCOPE_IDENTITY()", conn);
lastRecord = cmd.ExecuteScalar().ToString();
Use Stored Procedure only for the queries and use SCOPE_IDENTITY to get max value.
SqlCommand command = new SqlCommand("select max(id) from SocialGroup ", connection);
int lastId = (int)command.ExecuteScalar();
I've been trying to use the same SqlConnection and SqlCommand objects to execute to different commands.
the first one checks for duplicate and the second one inserts the data if the data the user entered is not a duplicate.
Here's a sample of my code:
using (SqlConnection conn = new SqlConnection(ConnStr))
{
string Command = "SELECT CountryName FROM [Countries] WHERE CountryName = #Name";
using (SqlCommand comm = new SqlCommand(Command, conn))
{
comm.Parameters.Add("#Name", System.Data.SqlDbType.NVarChar, 20);
comm.Parameters["#Name"].Value = Name;
comm.Parameters.Add("#IsVisible", System.Data.SqlDbType.Bit);
comm.Parameters["#IsVisible"].Value = IsVisible;
conn.Open();
if (comm.ExecuteScalar() == null)
{
Command = "INSERT INTO [Countries] (CountryName, IsVisible) VALUES (#Name, #IsVisible);";
comm.ExecuteNonQuery();
}
}
I was trying to save a trip to the database by using one connection.
The Problem is:
The first command runs okay but the
second command which inserts into the
database won't work (it doesn't add
any records to the db) and when I
tried to display the rows affected it
gave me -1 !!
The Question is:
Is this is the ideal way to check for
a duplicate records to constraint a
unique country ? and why the second
command is not executing ?
You are changing the value of string Command, but you are never actually changing the command string in SqlCommand comm.
When you rewrite the Command variable with the insert statement, you are simply modifying the string named Command that you've defined earlier. You are not modifying the command text stored inside of the SqlCommand object.
Try:
comm.CommandText = "INSERT INTO [Countries] (CountryName, IsVisible) VALUES (#Name, #IsVisible);";
To answer your first question: no, this is not the way to ensure uniqueness for country name. In your database, you should define your Countries table so that CountryName is the primary key (alternatively, you can declare some other column as the PK and define a unique constraint on CountryName).
The attempt to insert a duplicate value, then, will throw an exception, which you can handle appropriately (discard the existing record, overwrite it, prompt the user for a different value etc.).
Checking for uniqueness via your method is considered bad because A) it places logic that belongs in the database itself into your application's code; and B) it introduces a potential race condition, wherein some other application or thread inserts a value in between your read of the database and your write to it.
I thing i suggest to seperate the insert with your select statement..
someting like:
private void Insert()
{
using (SqlConnection conn = new SqlConnection(ConnStr))
{
string Command = "INSERT INTO [Countries] (CountryName, IsVisible) VALUES (#Name, #IsVisible)";
using (SqlCommand comm = new SqlCommand(Command, conn))
{
comm.Parameters.Add("#Name", System.Data.SqlDbType.NVarChar, 20);
comm.Parameters["#Name"].Value = Name;
comm.Parameters.Add("#IsVisible", System.Data.SqlDbType.Bit); comm.Parameters["#IsVisible"].Value = IsVisible;
conn.Open();
comm.ExecuteNonQuery();
conn.Close();
}
}
private void SelectInsert()
{
using (SqlConnection conn = new SqlConnection(ConnStr))
{
string Command = "SELECT CountryName FROM [Countries] WHERE CountryName = #Name";
using (SqlCommand comm = new SqlCommand(Command, conn))
{
comm.Parameters.Add("#Name", System.Data.SqlDbType.NVarChar, 20);
comm.Parameters["#Name"].Value = Name;
conn.Open();
if (comm.ExecuteScalar() == null)
{
Insert(); //your save method
}
}
}
Regards