Executescalar query code issue - c#

Im trying to return the member id in this query below. If i run the query as just as a query i get 20 but when i exectute the code it returns a zero. What am i doing wrong here?
public int GetMemberID(string guid)
{
string strConectionString = ConfigurationManager.AppSettings["DataBaseConnection"];
string StrSql = "SELECT MemberID FROM MEMBERS WHERE (Guid = #GuidID)";
int memberId;
using (var connection = new SqlConnection(strConectionString))
using (var command = new SqlCommand(StrSql, connection))
{
command.Parameters.Add("#GuidID", SqlDbType.Int).Value = guid;
memberId = (int)command.ExecuteScalar();
}
return memberId;
}

The guid variable is not an int.
command.Parameters.Add("#GuidID", SqlDbType.VarChar).Value = guid;

Your paramter #GuidID is an Int type?
Make sure it is right.

Related

SqlCommand Text multiple queries

I am using a list collection and i need to insert each item of my collection inside sql using also parameters.
Here is an example
foreach (var item in listCollection)
{
cmd.CommandText += "Insert into WebAppOrders (id) values (#id)";
cmd.Parameters.Add("#id", SqlDbType.Int).Value = item.id;
}
cmd.ExecuteNonQuery();
I am getting an error
The variable name '#id' has already been declared. Variable names must be unique within a query batch or stored procedure.
Is there any way which I can make this work?
You can use a simple count variable, which you then append to the parameter-name #id.
A sample would look like...
Example Item-class:
public class Item
{
public Item(int id)
{
this.Id = id;
}
public int Id { get; set; }
}
Simulation:
var listCollection = new List<Item>() { new Item(1), new Item(2), new Item(3), new Item(4) };
using (var connection = new SqlConnection("<your connectionstring>"))
using (var cmd = new SqlCommand("", connection))
{
connection.Open();
int i = 0; // count
foreach (var item in listCollection)
{
cmd.CommandText += $"Insert into WebAppOrders (id) values (#id{i})"; // add count here
cmd.Parameters.Add($"#id{i}", SqlDbType.Int).Value = item.Id; // ... and here
i++;
}
cmd.ExecuteNonQuery();
}

C# SQL stored procedure call values

Trying to communicate with the database, I am little bit confused about how to pass a value as a parameter(for ex. an itemID) and get back the records that are having this ID.
Here is my stored procedure:
ALTER PROCEDURE [dbo].[sp_lightItem]
(
#itemID INT
)
AS
BEGIN
SELECT [itemID],
[itemName],
[itemLocation],
[itemChBy]
FROM [dbo].[Item]
WHERE itemSystemType='E' and itemID=#itemID ORDER BY itemID DESC;
END
And this is my c# code so far..
public string LoadItemNew(int ItemID)
{
var acf = new AcFunctions();
var newstorevalue = SqlHelper.ExecuteDataset(acf.AcConn(), "sp_lightItem", ItemID);
}
As you can see in stored procedure, what I want is to get back those 4 elements:
[itemID],[itemName],[itemLocation],[itemChBy]
Unfortunately I do not know how to get them back/how to call them in c# function.
Any help is welcome.
i dont have enough repo to comment , can you provide the definition of
AcFunctions();
i am sure you it must be returning ConnectionString
try this
public string LoadItemNew(int ItemID)
{
var acf = new AcFunctions();
var newstorevalue = SqlHelper.ExecuteDataset(acf.AcConn(), "sp_lightItem", new SqlParameter ("#itemID",ItemID));
}
Edit 1
try this
public string LoadItemNew(int ItemID)
{
List<string> testList = new List<string>();
var acf = new AcFunctions();
var newstorevalue = SqlHelper.ExecuteReader(acf.AcConn(), "sp_lightItem", new SqlParameter ("#itemID",ItemID));
if(newstorevalue.HasRows)
{
while(newstorevalue.Read())
{
testList.Add(newstorevalue["itemID"].ToString());
testList.Add(newstorevalue["itemName"].ToString());
testList.Add(newstorevalue["itemLocation"].ToString());
testList.Add(newstorevalue["itemChBy"].ToString());
}
}
}
You can try with this approach, I will use Data Transfer Object for holding data retrieved from database and Execute DataReader for reading.
First of all, you need to create a DTO class, I will call it LightItemDTO
public class LightItemDTO
{
public int Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public string ChangedBy { get; set; }
}
Note: How to know the type of properties, you can reference this link: SQL Server Data Type Mappings
And now, I will using ADO.NET for execute the stored procedure to get data from database
public IEnumerable<LightItemDTO> GetLightItem(string itemText, string sqlConnectionString)
{
var results = new List<LightItemDTO>();
using (var con = new SqlConnection(sqlConnectionString))
{
using (var cmd = new SqlCommand("sp_lightItem", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#ItemID", SqlDbType.VarChar).Value = itemText;
con.Open();
using (var reader = cmd.ExecuteReader())
{
results.Add(new LightItemDTO
{
Id = Convert.ToInt32(reader["itemID"]),
Name = reader["itemName"].ToString(),
Location = reader["itemLocation"].ToString(),
ChangedBy = reader["itemChBy"].ToString()
});
}
}
}
return results;
}
Using DataReader is the best practice with high performance.
ADO.NET is the manual way to achieve this task, you can use some ORM framework for do it easier, such as: Entity Framework, Dapper.NET ...
You could execute stored procedure with parameters in following:
using (SqlConnection con = new SqlConnection(dc.Con)) {
using (SqlCommand cmd = new SqlCommand("sp_lightItem", con)) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#ItemID", SqlDbType.VarChar).Value = itemId.Text;
con.Open();
cmd.ExecuteNonQuery();
}
}
first of all set the Commandtype as stored procedure and that procedure will return some data which you will save in dataset and then return the data set to where ever you want to populate the data
public DataSet LoadItemNew(int ItemID)
{
var acf = new AcFunctions();
return DataSet ds = SqlHelper.ExecuteDataset(acf.AcConn(),CommandType.StoredProcedure, "sp_lightItem",new SqlParameter("#itemID" ItemID);
}
You can try like this ..
public string LoadItemNew(int ItemID)
{
var acf = new AcFunctions();
List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("#itemID", ItemID));
DataSet Ds = SqlHelper.ExecuteDataset(acf.AcConn(),CommandType.StoredProcedure, "sp_lightItem" , parameters.ToArray());
return "ok";
}

how to convert row value from sql server to string in c#

I have a method like this
private string AccountCreation()
{
string accountId="";
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
StringBuilder sql = new StringBuilder();
sql.AppendLine("SELECT ACCOUNT_ID,CUSTOMER_ID FROM T_ACCOUNT order by ACCOUNT_ID desc");
sql.AppendLine("SET IDENTITY_INSERT T_ACCOUNT ON");
sql.AppendLine("INSERT INTO T_ACCOUNT (ACCOUNT_ID,CUSTOMER_ID)");
sql.AppendLine("SELECT ACCOUNT_ID + 1, CUSTOMER_ID +1 FROM T_ACCOUNT Where ACCOUNT_ID = (select max(ACCOUNT_ID) from T_ACCOUNT)");
sql.AppendLine("SET IDENTITY_INSERT T_ACCOUNT OFF");
accountId = Convert.ToString(sql.AppendLine("SELECT top 1 ACCOUNT_ID FROM T_ACCOUNT order by ACCOUNT_ID desc"));
string strUpdateQuery = sql.ToString();
ExecuteQuery(strUpdateQuery, command);
}
return accountId;
}
Now accountId is holding the query but not the value returned after execution of the query. I want the value in that string. Can anyone help me?
For getting value from the query. you need ExecuteScalar method.
object oRetVal = command.ExecuteScalar();
string accountId = string.Empty;
if(oRetVal != null)
{
accountId = oRetVal.ToString();
}
However, it is recommend to use store procedure.
I assume you are looking for the "TOP 1 Account_ID" from the query. What you have done there will not work (or give you what you want). You will need to either send in a output parameter to put the accountID in, or run fetch the data using datareader or dataset.
You'll have to bind the output of your ExecuteQuery to an object.
check if this returns any result and populates the accID.
var accID = ExecuteQuery(strUpdateQuery, command)
public string ExecuteQuery(string query,SqlCommand cmd)
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
object i=cmd.ExecuteScalar();
return i.ToString();
}
After this just assign this to the accounted
accountId = ExecuteQuery(strUpdateQuery, command);

Delete data from sql database not working

when you select items from the listbox, you want to delete selecteditems. Why doesnt it work when selected data removed from database? I must have missed something. I got error message
No mapping exists from object type.
This is a method parameter:
IsDelete = _dinnerRemover.RemoveDinners(lstDinner.SelectedItems);
This class is to delete data from database
public bool RemoveDinners(dynamic dinnerItems)
{
Dinners = new List<FoodInformation>();
using (var sqlConn = new SqlConnection(_sqlConnectionString))
{
const string sqlQuery = "delete from DinnerTemplates where Dinner = #dinner";
using (var command = new SqlCommand(sqlQuery, sqlConn))
{
try
{
//command.CommandType = CommandType.StoredProcedure;
//command.CommandText = "sp_dinner";
foreach (var item in dinnerItems)
{
command.CommandType = CommandType.Text;
command.Parameters.AddWithValue("#dinner", item);
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
sqlConn.Close();
}
}
}
return Dinners;
}
If dinnerItems is a list of strings then say that, don't use dynamic unless you absolutely have to.
To delete a bunch of items, issue one sql query with an IN clause. Don't issue lots of individual queries.
Try this:
public int RemoveDinners(List<string> dinnerItems)
{
using (var sqlConn = new SqlConnection(_sqlConnectionString))
{
const string sqlQuery = "delete from DinnerTemplates where Dinner in ({0})";
using (var command = new SqlCommand())
{
var paramNames = new string[dinnerItems.Count];
int i = 0;
foreach (string item in dinnerItems)
{
string paramName = "#Dinner" + i;
command.Parameters.AddWithValue(paramName, item);
paramNames[i] = paramName;
i += 1;
}
command.CommandText = String.Format(sqlQuery, String.Join(",", paramNames));
command.Connection = sqlConn;
command.CommandType = CommandType.Text;
sqlConn.Open();
return command.ExecuteNonQuery();
}
}
}
You have to bear in mind that you kind of left out some really relevant code, like what is a DinnerItem, since you're getting the error on a line related to its type.
However, the reason you're getting that error is because item can't be marshaled to a type of something like string or int.
That's probably because item is likely a custom class. One option would be to override the ToString method of the class:
public override string ToString() {
// return some property value, or set of property values
// strung together here.
}
another option would be to send in the actual Property you want off of item when issuing AddWithValue.
You need to define SqlDbType for command's parameter.
don't use dynamic type,use string..
if i were you,i would rather
IsDelete = _dinnerRemover.RemoveDinners(lstDinner.SelectedItems.ToString());
change the parameter to :
public bool RemoveDinners(string dinnerItems)
and the query to :
const string sqlQuery = "delete from DinnerTemplates where Dinner = dinnerItems";

Cast error in C#

I have a function in a class "Checkout" that runs a sql statement to insert a record into a table, then select the scope_identity, giving me the ID of that record. It returns the ID as an int, and I assign it to a variable in the webpage:
int OrderID = Checkout.WriteOrder_tblOrders(CustID);
Here's the function:
public static int WriteOrder_tblOrders(int CustID)
{
// OrderID is initially 0, then changed when scope_identity is called in the sql statement.
int OrderID = 0;
DateTime OrderDate = DateTime.Now;
string sql = "INSERT INTO tblOrders (OrderDate, CustID) VALUES (#OrderDate, #CustID); SELECT scope_identity();";
using (SqlConnection myConnection = new SqlConnection(connectString))
{
using (SqlCommand cmd = new SqlCommand(sql, myConnection))
{
cmd.Parameters.AddWithValue("#CustID", CustID);
cmd.Parameters.AddWithValue("#OrderDate", OrderDate);
myConnection.Open();
OrderID = (int)cmd.ExecuteScalar();
myConnection.Close();
}
}
return OrderID;
}
The debugger shows that there's nothing wrong with the function, and new records are showing up correctly in that table, but I'm getting an
"Invalid Cast"
error on the first line, where I assign OrderID. I've tried this:
int OrderID = (int)Checkout.WriteOrder_tblOrders(CustID);
With both int and Int32, and also tried using Convert.ToInt32, which didn't work either. What am I doing wrong here?
The reason may be you are getting null values.
So you ca create an extension method as follows
public static T ExecuteNullableScalar<T>(this SqlCommand cmd) where T : struct
{
var result = cmd.ExecuteScalar();
if (result == DBNull.Value) return default(T);
return (T)result;
}
Usage becomes:
int value = cmd.ExecuteNullableScalar<int>();
//new approach
ulong value=cmd.ExecuteNullableScalar<ulong>();
Other-Wise
myConnection.Open();
var o = cmd.ExecuteScalar();
OrderID = (o== DBNull.Value ? 0 : Convert.ToUInt64(o));
myConnection.Close();
changed
OrderID = (o== DBNull.Value ? 0 : Convert.ToUInt64(o));
Thanks for your help guys, didn't realize that scope_identity returns a decimal. I altered the code like this:
OrderID = Convert.ToInt32((decimal)cmd.ExecuteScalar());
It now works fine. Thanks!

Categories

Resources