I have procedure like this?
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `check_user`(in username varchar(100), in pass varchar(5000))
BEGIN
select * from users where email=username and password = pass;
END$$
DELIMITER ;
So i call procedure like this.
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "get_user";
cmd.Parameters.AddWithValue("#username", un);
cmd.Parameters.AddWithValue("#pass", Security.Encrypt(pass));
int result = cmd.ExecuteNonQuery();
it shows result as 0. Because not any row affected. In this case can't identify user is exist or not. User exist or not result always 0. So how can i get user is exist or not ?
ExecuteNonQuery should not be used in SELECT statements.
ExecuteNonQuery method is to be used to perform 'Data Manipulation Language'. This is used only in INSERT, DELETE and UPDATE.
ExecuteScalar method will return a single value in the first row, first column from a SELECT statement. So changing your query with SELECT COUNT(*).. can be use.
The ExecuteReader Method will return the result set of a SELECT. This method is to be used when you're querying for a bunch of results, such as rows from a table etc.
Change your query with this:
SELECT COUNT(*) FROM users WHERE email=username AND password = pass;
And use ExecuteScalar() and you are ready to go.
Or you can use DataAdapter Fill like this:
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "get_user";
cmd.Parameters.AddWithValue("#username", un);
cmd.Parameters.AddWithValue("#pass", Security.Encrypt(pass));
DataTable data = new DataTable();
using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
{
da.Fill(data);
}
if (data.Rows.Count > 0)
result = Convert.ToInt32(data.Rows[0][0].ToString());
Read more here.
Related
I'm trying to get a count of column records in a Sql database and show the result in a MessageBox.
This is my code:
public DataTable CheckIfNameExist(string name)
{
con = Connect();
cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "spCheckIfNameExist";
cmd.Parameters.AddWithValue("#Name", SqlDbType.NVarChar).Value = name;
MessageBox.Show(name);
Int32 totalNames = (Int32) cmd.ExecuteScalar();
string tNames = totalNames.ToString();
MessageBox.Show(tNames);
}
And this is my sp:
#Name nvarchar(50) = null
As
Begin
SELECT COUNT(*) from OrdersSent where CustomerName LIKE #Name + '%'
End
Problem:
It always returns 0.
There are a couple of errors in your code:
You should write it as:
cmd.CommandText = "spCheckIfNameExist";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = name;
First you need to tell the ADO engine that you are calling a stored procedure and not a simple command text, but you also need to use Add instead of AddWithValue to be precise on the type of the parameter passed to the SP. Your code creates a parameter int becase the second parameter of the AddWithValue is the Value of the parameter not the type.
You have a few problems in the c# code - the most important is probably this:
cmd.Parameters.AddWithValue("#Name", SqlDbType.NVarChar).Value = name;
Don't use AddWithValue. Use Add.
Also, you didn't specify the command type - the default is Text.
And you are using fields for SqlConnection and SqlCommand - which is also the wrong thing to do. You should create and dispose both of them inside each method you are using them.
A better version of your code would be this:
using(var con = new SqlConnection(ConnectionString))
{
using(var cmd = new SqlCommand("spCheckIfNameExist", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = name;
con.Open();
var tNames = cmd.ExecuteScalar().ToString();
}
}
Another thing that puzzles me is why a method called CheckIfNameExist returns a DataTable. I would expect it to simply return a bool.
If you really only want to check if the name exists, you can do this better on both the SQL level and the c# level.
A better SQL would be something like this:
SELECT CAST(CASE WHEN EXISTS(
SELECT 1
FROM OrdersSent
WHERE CustomerName LIKE #Name + '%'
) THEN 1 ELSE 0 END AS bit)
And on the c# level, bit translates directly to bool, so the code can simple be this:
public bool CheckIfNameExist(string name)
{
using(var con = new SqlConnection(ConnectionString))
{
using(var cmd = new SqlCommand("spCheckIfNameExist", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = name;
con.Open();
return (bool)cmd.ExecuteScalar();
}
}
}
And another note - you should avoid using the sp prefix for stored procedures.
Microsoft have reserved this prefix for built in system procedures.
For more information, read Aaron Bertrand's Is the sp_ prefix still a no-no?, where you'll see that the short answer to this question is "Yes".
The sp_ prefix does not mean what you think it does: most people think sp stands for "stored procedure" when in fact it means "special." Stored procedures (as well as tables and views) stored in master with an sp_ prefix are accessible from any database without a proper reference (assuming a local version does not exist). If the procedure is marked as a system object (using sp_MS_marksystemobject (an undocumented and unsupported system procedure that sets is_ms_shipped to 1), then the procedure in master will execute in the context of the calling database.
You need to specify the type of your command like this:
cmd.CommandText = "spCheckIfNameExist";
cmd.CommandType = CommandType.StoredProcedure;
See also:
What is the benefit of using CommandType.StoredProcedure versus using CommandType.Text?
Although specify the type directly and use the Value property is more better than AddWithValue:
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = name;
The following article could be also interesting:
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
I have a stored procedure that correctly returns records when I call it from a SSMS query.
Here is the stored procedure:
CREATE PROCEDURE [dbo].[q_CheckRecords]
#ItemIDS AS VARCHAR(40)
AS
BEGIN
SET NOCOUNT ON
SELECT *
FROM q_Warehouse80_OOS_ItemsNeedingNotification
WHERE item_id = #ItemIDS
END
Calling this from a SSMS query like this:
exec [q_CheckOOSWarehouse80ItemsNeedingNotification] 'B30-R10000-B001'
It correctly returns a row, however when I use this C# code to call the stored procedure, I never get any rows returned.
SqlCommand cmd = null;
SqlDataReader myReader = null;
System.Data.SqlClient.SqlConnection conn = null;
conn = new System.Data.SqlClient.SqlConnection("Data Source=" + sSessionServer + ";database=" + sSessionDatabase + "; Integrated Security=SSPI");
String SQL = "[q_CheckOOSWarehouse80ItemsNeedingNotification]";
cmd = new SqlCommand();
cmd.CommandText = SQL;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Connection = conn;
cmd.Parameters.Add("#ItemIDS", SqlDbType.VarChar).Value = ItemsToBeChecked;
conn.Open();
myReader = cmd.ExecuteReader();
// check to see if any rows were returned.
if (myReader.HasRows)
{
while (myReader.Read())
{
// code to read fields in returned rows here
}
}
conn.Close();
It appears to be a problem with how C# defines the datatype being passed to the stored procedure, but I haven't found any information online on how to solve this problem.
If I were to changed the stored procedure so it's "hard coded"
#ItemIDS AS VARCHAR(40)
AS
BEGIN
SET NOCOUNT ON
select * from q_Warehouse80_OOS_ItemsNeedingNotification where item_id = 'B30-R10000-B001'
END
then the C# call to it correctly indicates that a row was "found".
Any help would be greatly appreciated.
When you don't specify the length of a varChar sql treats it as length 1.
cmd.Parameters.Add("#ItemIDS", SqlDbType.VarChar).Value = ItemsToBeChecked;
Your variable ItemsToBeChecked will be truncated, and I suspect there is nothing matching in your database with just the first character of that value.
Specify the length of the varchar
cmd.Parameters.Add("#ItemIDS", SqlDbType.VarChar, 40).Value = ItemsToBeChecked;
You can verify this is the case by putting a profiler on sql, and executing your c#. You will see the value passed to the #ItemIDS parameter is only 1 character long.
The issue you are facing is because you are not calling your stored procedure in your C# Code.
I am learning how to work with SQL in C#, and I got in troubles with using SqlDataAdapter. I have tried to use direct queries via SqlCommand class and everything works fine, but when I rewrote my code to use SqlDataAdapter I have no changes in my table. There is my code:
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ADO"]
.ConnectionString);
connection.Open();
SqlDataAdapter daUser = new SqlDataAdapter("SELECT * FROM Books", connection);
SqlCommand insert = new SqlCommand();
insert.Connection = connection;
insert.CommandText = "INSERT INTO Books (name, author) VALUES (#name, #author);";
SqlParameterCollection pc = insert.Parameters;
pc.Add("#name", SqlDbType.VarChar, 20, "test123");
pc.Add("#author", SqlDbType.VarChar, 20, "test322");
daUser.InsertCommand = insert;
DataSet ds = new DataSet();
daUser.Fill(ds, "Books");
daUser.Update(ds, "Books");
Table Books was created with this SQL query in SQL Server Management Studio:
CREATE TABLE Books
(
id int PRIMARY KEY IDENTITY(1,1),
name varchar(MAX) NOT NULL,
author varchar(MAX) NOT NULL
)
INSERT INTO Books(name, author)
VALUES('1984', 'George Orwell'), ('Fathers and sons', 'Dostoevski')
Looks like I am missing something to do, that why my code have no effect on table.
SqlDataAdapter.Update will call its InsertCommand only for the rows of datatable having RowState = DataRowState.Added.
This rowstate is automatically assigned to the datarows being added to rows collection using DataTable.Add method (until next call to AcceptChanges method). Also you can use DataRow.SetAdded method to force this state assignment.
Since you're not modifying/adding anything in you datatable after you've populated it with select command, it has nothing to insert.
Change your code to something like
daUser.Fill(ds, "Books");
var newBook = daUser.Tables[0].NewRow();
newBook["name"] = "New Book";
newBook["author"] = "Author Name";
daUser.Tables[0].Rows.Add(newBook);
daUser.Update(ds, "Books");
and in this case it should be new row added to the database table.
See MSDN for reference.
Just to clarify the previous answer, which is correct, you want to call ExecuteNonQuery() on the command not the dataAdapter.
SqlCommand insert = new SqlCommand();
insert.Connection = connection;
insert.CommandText = "INSERT INTO Books (name, author) VALUES (#name,
#author);";
SqlParameterCollection pc = insert.Parameters;
pc.Add("#name", SqlDbType.VarChar, 20, "test123");
pc.Add("#author",
SqlDbType.VarChar, 20, "test322");
// you do not need this line if you execute the insert on the command object.
// daUser.InsertCommand = insert;
//Add this line instead:
insert.ExecuteNonQuery();
Joey
I'm trying to hit the stored procedure from C# code but always get the result == -1. I don't know where I went wrong. I have searched a lot but didn't' find any solution. Please have a look into my code snippet and guide me what I'm doing wrong.
Thanks in advance.
C# code:
using (SqlConnection connection = new SqlConnection(getConnectionString()))
using (SqlCommand command = new SqlCommand())
{
Int32 rowsAffected;
command.CommandText = "SP_LOGIN_GETUSERBYNAME";
command.CommandType = CommandType.StoredProcedure;
// command.Parameters.Add(new SqlParameter("#Email", userObj.email));
// command.Parameters.Add("#Email", SqlDbType.VarChar).Value = userObj.email.Trim();
command.Parameters.AddWithValue("#Email", userObj.email.ToString());
command.Connection = connection;
connection.Open();
rowsAffected = command.ExecuteNonQuery();
connection.Close();
return rowsAffected;
}
Connection string:
return "Data Source=MUNEEB-PC;Initial Catalog=HRPayRoll;User ID=sa; Password=sa";
Stored procedure code:
CREATE PROCEDURE SP_LOGIN_GETUSERBYNAME
#Email varchar(50)
AS
SELECT *
FROM [User]
WHERE Email = #Email
GO
From ExecuteNonQuery doc;
For UPDATE, INSERT, and DELETE statements, the return value is the
number of rows affected by the command. When a trigger exists on a
table being inserted or updated, the return value includes the number
of rows affected by both the insert or update operation and the number
of rows affected by the trigger or triggers. For all other types of
statements, the return value is -1
Since your command is SELECT, it is too normal to get -1 as a return value.
If you wanna reach your results, you can use ExecuteReader method instead.
var reader = command.ExecuteReader();
while (reader.Read())
{
// This will iterate your results line by line and
// You can get columns with zero-based values like reader[0], reader[1] or
// can use GetXXX methods of it like GetString(0) or GetInt32(1) etc.
}
In the database I created a stored procedure
ALTER procedure [dbo].[usercusdet_pro](#user varchar(25),#cusname varchar(max))--,#cnt int)
as
begin
--declare #count int
--set #count=0
--if(#count<#cnt)
insert usercusdet values(#user,#cusname)
end
to insert values. When I click the button, multiple rows should be inserted in the table.
int cnt = gvTranferRows.Rows.Count;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["gdb"].ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("usercusdet_pro", con);
cmd.CommandType = CommandType.StoredProcedure;
if (con.State == ConnectionState.Closed)
con.Open();
for (int i=0;i<cnt;i++)
{
cmd.Parameters.Add("#user", SqlDbType.VarChar).Value = "A001";
cmd.Parameters.AddWithValue("#cusname",gvTranferRows.Rows[i].Cells[0].Text);
//cmd.Parameters.AddWithValue("#cnt", cnt);
cmd.ExecuteNonQuery();
}
When I try to add value it shows an error:
procedure or function has too many arguments specified
What's the cause of this error?
You need to clear the parameters before the next iteration i.e.
cmd.Parameters.Add("#user", SqlDbType.VarChar).Value = "A001";
cmd.Parameters.AddWithValue("#cusname",gvTranferRows.Rows[i].Cells[0].Text);
//cmd.Parameters.AddWithValue("#cnt", cnt);
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
Or given the #user parameter is fixed, you just need to replace the #cusname one
cmd.Parameters.Add("#user", SqlDbType.VarChar).Value = "A001";
for (int i=0;i<cnt;i++)
{
cmd.Parameters.AddWithValue("#cusname",gvTranferRows.Rows[i].Cells[0].Text);
cmd.ExecuteNonQuery();
cmd.Parameters.RemoveAt("#cusname");
}
You can use Table valued parameter starting sql server 2008 onwards.
OR
Youc an go for passing data as XML if using version prior to SQL Server 2008.
OR
Not a good apporach but you can use delimiter seperated string as well.