Unable to open connection using a "using var parameterized queries" - c#

I have this scenario:
I have a table called "Entradas" and one called "Saidas". Both have
the column "data" and "hora". With that in mind, since the "data" and
"hora column of "entradas" mean that a car joined at that date and
time, and the values from the columns "data" and "hora" of "saidas"
are mean to be inserted as i click a button, inserting the current
date and time. I'm requesting a sql syntax that could insert the
values "data" and "hora" into the table "saidas" and update a value of
"entradas" called "sai" which is equal to 0 and i want it to change to
1 on button press.
And i have this procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `entradas_sai`(
IN ID_VEICULO VARCHAR(45), OUT retcode INT)
BEGIN
DECLARE _rollback BOOL DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET _rollback = 1;
START TRANSACTION;
INSERT INTO SAIDAS(data, hora) VALUES(date(now()) ,time(now()));
UPDATE ENTRADAS SET SAI=1;
IF '_rollback' THEN
SET retcode = 0;
ROLLBACK;
ELSE
SET retcode = 1;
COMMIT;
END IF;
END
And this is my actual code to run it on button click:
private void cmdSaida_Click(object sender, EventArgs e)
{
using (var cn = new MySqlConnection("server=localhost;user id=root;password=12345;persistsecurityinfo=True;database=portaria;allowuservariables=True"))
{
cn.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "entradas_sai";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ID_veiculo", Grid1.SelectedCells[1].Selected);
cmd.Parameters["#id_veiculo"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("#retcode", MySqlDbType.Int32);
cmd.Parameters["#retcode"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
var res = cmd.Parameters["#retcode"].Value;
cn.Close();
}
}
And my problem at the moment is that when i click the button, it doesn't execute my procedure neither my commands to open or close the connection. Any sugestions?
EDIT: After some research i found that my actual procedure sets all the values from 0 to 1 in column "sai" how can i do it so it only change the selected grid row value, based on "ID_Entrada"

You have a MySqlCommand object, but it's not associated with any connection. There has to be an active connection in order to execute a command.
You can associate it on the constructor:
MySqlCommand cmd = new MySqlCommand("entradas_sai", cn);
or after the constructor:
cmd.Connection = cn;

Related

insert value from TextBox into sql

I'm getting this error message: Cannot insert the value NULL into column 'id', table ''; column does not allow nulls. INSERT fails. thanks in advance
protected void AddItem(object sender, EventArgs e)
{
string insertCmd = "INSERT INTO Picture (Album, id) VALUES (#Album, #id)";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["strConn"].ConnectionString))
{
conn.Open();
SqlCommand myCommand = new SqlCommand(insertCmd, conn);
// Create parameters for the SqlCommand object
// initialize with input-form field values
myCommand.Parameters.AddWithValue("#Album", txtAlbum.Text);
myCommand.Parameters.Add("#id", SqlDbType.Int).Direction = ParameterDirection.Output;
myCommand.ExecuteNonQuery();
int id = (int)myCommand.Parameters["#id"].Value;
}
}
I suppose that ID is an IDENTITY column. Its value is generated automatically by the database engine and you want to know what value has been assigned to your record.
Then you should change your query to
string insertCmd = #"INSERT INTO Picture (Album) VALUES (#Album);
SELECT SCOPE_IDENTITY()";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["strConn"].ConnectionString))
{
conn.Open();
SqlCommand myCommand = new SqlCommand(insertCmd, conn);
myCommand.Parameters.AddWithValue("#Album", txtAlbum.Text);
int newID = Convert.ToInt32(myCommand.ExecuteScalar());
}
The query text now contains a second instruction SELECT SCOPE_IDENTITY() separated from the first command by a semicolon. SCOPE_IDENTITY returns the last IDENTITY value generated for you by the database engine in the current scope.
Now the command is run using the ExecuteScalar to get back the single value returned by the last statement present in the query text without using any output parameter
I would think that ID is identity. You don't have to add this value. I would try the following code and check the database if you get automatically an ID.
string insertCmd = "INSERT INTO Picture (Album) VALUES (#Album)";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["strConn"].ConnectionString))
{
conn.Open();
SqlCommand myCommand = new SqlCommand(insertCmd, conn);
// Create parameters for the SqlCommand object
// initialize with input-form field values
myCommand.Parameters.AddWithValue("#Album", txtAlbum.Text);
myCommand.ExecuteNonQuery();
}
I case you want to set the id yourself(withoud automatic increment from the db), you should change the schema of the database removing identity from ID as shown below:
I hope this helps
If you need to stay this column empty you can try to replace to ' '(blank). This will work if you column is not "Key"
Or try to use:
substitute a value when a null value is encountered
NVL( string1, replace_with )
You can do this using stored procedure. Below is the script for Create stored procedure.
CREATE PROCEDURE [dbo].[InsertIntoPicture]
#Album varchar(500)=null,
#id int=0 output
AS
BEGIN
insert INTO Picture(Album)VALUES(#Album)
SET #id=##IDENTITY
END
Below is the code for call stored procedure with C# .
string insertCmd = "InsertIntoPicture";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["strConn"].ConnectionString))
{
conn.Open();
SqlCommand myCommand = new SqlCommand(insertCmd, conn);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue("#Album", txtAlbum.Text);
myCommand.Parameters.Add("#id", SqlDbType.Int).Direction = ParameterDirection.Output;
myCommand.ExecuteNonQuery();
int id = (int)myCommand.Parameters["#id"].Value;
}
Using above code you can insert a date from TextBox and also get last inserted record ID as an output variable as per your requirement.
Thanks .

Stored Procedure doesn't return records when called from C#, but works in SSMS

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.

How do i display a select stored procedure result in a textbox?

I need to display the result from a select statement in a stored procedure onto the textbox and I can't figure out how to do it. The select statement doesn't use a WHERE clause. The stored procedure goes
CREATE PROCEDURE NewCustomer
AS
BEGIN
SELECT MAX(ID) + 1 FROM Database
END
This is what I've tried
protected void btnNew_Click(object sender, EventArgs e)
{
Clear();
int num;
try
{
using (SqlCommand command = new SqlCommand("NewCustomer"))
{
command.Connection = conn;
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#CustID", SqlDbType.Int).Value = Int32.TryParse(txtCID.Text, out num); // Use tryparse if needed
conn.Open();
txtCID.Text = (string)command.ExecuteScalar();
}
}
catch (Exception ex)
{
lblMessage.Text = ex.Message;
}
}
It gives me a "Procedure NewCID has no parameters and arguments were supplied." Error
You are not executing the procedure that you ware given. The procedure is named as yadayada(The worst name that you can give) and you are executing the procedure NewCustomer as the command text. Both has to be same. Then you are using the Wrong statement for executing the query.
The ExecuteNonQuery to perform catalog operations (for example,
querying the structure of a database or creating database objects such
as tables), or to change the data in a database without using a
DataSet by executing UPDATE, INSERT, or DELETE statements.
But you are using it for executing the select query. Here you are selecting a single value from the table so the ExecuteScalar will be the best option for you. Your code will be like this: assume the procedure name is GetNewCustomerID;
using (SqlCommand exeCommand = new SqlCommand("GetNewCustomerID"))
{
exeCommand.Connection = conn;
exeCommand.CommandType = CommandType.StoredProcedure;
exeCommand.Parameters.Add("#CustID",SqlDbType.Int).Value=Convert.ToInt32(txtCID.Text); // Use tryparse if needed
conn.Open();
txtCID.Text = (string)exeCommand.ExecuteScalar();
}

Unable to get data from stored procedure

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.
}

How to store multiple rows in single button click using stored procedure

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.

Categories