Issue in update records in c# - c#

Here is searchupdate_Click code:
protected void searchupdate_Click(object sender, EventArgs e)
{
SqlConnection con = Connection.DBconnection();
{
SqlCommand com = new SqlCommand("sp_searchupdate", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#id", textstudentid.Text);
SqlDataAdapter adp = new SqlDataAdapter(com);
DataSet ds = new DataSet();
adp.Fill(ds);
txttamil.Text = ds.Tables[0].Rows[0]["Tamil"].ToString();
txtenglish.Text = ds.Tables[0].Rows[0]["English"].ToString();
txtmaths.Text = ds.Tables[0].Rows[0]["Maths"].ToString();
txtscience.Text = ds.Tables[0].Rows[0]["Science"].ToString();
txtsocialscience.Text = ds.Tables[0].Rows[0]"SocialScience"].ToString();
}
}
When I enter student id and search, it showed student marks in textboxes.
After that I want to edit and update.
For that I have added above code, and here its stored procedure:
ALTER PROCEDURE sp_searchupdate
(
#id int,
#Tamil varchar(50),
#English varchar(50),
#Maths varchar(50),
#Science varchar(50),
#SocialScience varchar(50)
)
AS
IF EXISTS (SELECT * FROM studentresult WHERE id_student='#id')
begin
SELECT id_student FROM studentresult WHERE id_student='#id'
END
When I edit marks, and hit update button, it shows error.
Here is my output screenshot
May I know, what my mistake in the code, I'm new to .net.
Can anyone help me?
update:
ALTER PROCEDURE sp_searchupdate
(
#id int,
#Tamil Varchar (100),
#English varchar (50),
#Maths Varchar (50),
#Science Varchar (50),
#SocialScience Varchar (50)
)
AS
IF EXISTS (SELECT * FROM studentresult WHERE id_student=#id)
BEGIN
UPDATE studentresult SET Tamil = #Tamil,English = #English, Maths = #Maths,Science = #Science,SocialScience = #SocialScience WHERE id = #id
END

Since your SP expects parameters.
You have to pass the expected parameters to the stored procedure from C#. Like below,
btnSearch_Click
com.Parameters.AddWithValue("#Tamil", "");
com.Parameters.AddWithValue("#English", "");
com.Parameters.AddWithValue("#Maths", "");
com.Parameters.AddWithValue("#Science", "");
com.Parameters.AddWithValue("#SocialScience", "");
btnUpdate_Click
// Add your Parameter
cmd.Parameters.AddWithValue("#id", txtstudentid.Text);
cmd.Parameters.AddWithValue("#tamil", txttamil.Text);
cmd.Parameters.AddWithValue("#english", txtenglish.Text);
cmd.Parameters.AddWithValue("#math", txtmaths.Text);
cmd.Parameters.AddWithValue("#science", txtscience.Text);
cmd.Parameters.AddWithValue("#socialScience", txtsocialscience.Text);

First at all you must understand how your current code work...
Let's say when you click searchupdate this should do what kind of job?
Now base on your code now is actually setting the TextBox to the Database value you retrieve.
Is this what you expect ? Answer is NO
I have separated to 2 button due to your function 1 is for search and another 1 is for update....
// This is First Button
protected void btnSearch_Click(object sender, EventArgs e)
{
// What does theis code here do ??
SqlConnection con = Connection.DBconnection();
{
SqlCommand com = new SqlCommand("PROCEDURE_SELECT", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#id", txtstudentid.Text.Trim());
SqlDataAdapter adp = new SqlDataAdapter(com);
DataSet ds = new DataSet();
adp.Fill(ds);
// SEt value to TextBox & make sure your value below is not Null else it will throw you null exception due to you use .ToString()
txttamil.Text = ds.Tables[0].Rows[0]["Tamil"].ToString();
txtenglish.Text = ds.Tables[0].Rows[0]["English"].ToString();
txtmaths.Text = ds.Tables[0].Rows[0]["Maths"].ToString();
txtscience.Text = ds.Tables[0].Rows[0]["Science"].ToString();
txtsocialscience.Text = ds.Tables[0].Rows[0]["SocialScience"].ToString();
}
}
// This is second Button
protected void btnUpdate_Click(object sender, EventArgs e)
{
using (SqlConnection con = Connection.DBconnection())
{
using (SqlCommand cmd = new SqlCommand("PROCEDURE_UPDATE", con))
{
cmd.CommandType = CommandType.StoredProcedure;
// Add your Parameter
cmd.Parameters.AddWithValue("#id", txtstudentid.Text.Trim());
cmd.Parameters.AddWithValue("#tamil", txttamil.Text.Trim());
cmd.Parameters.AddWithValue("#english", txtenglish.Text.Trim());
cmd.Parameters.AddWithValue("#math", txtmaths.Text.Trim());
cmd.Parameters.AddWithValue("#science", txtscience.Text.Trim());
cmd.Parameters.AddWithValue("#socialScience", txtsocialscience.Text.Trim());
con.Open();
// Execute your Query
cmd.ExecuteNonQuery();
// Clear All The Data in Current TextBOx and press search again with the ID
txttamil.Text = string.Empty;
txtenglish.Text = string.Empty;
txtmaths.Text = string.Empty;
txtscience.Text = string.Empty;
txtsocialscience.Text = string.Empty;
Response.Write("You have updated the value... Try to Search again...");
}
// UPDATE Query as per below
// IF EXISTS (SELECT * FROM studentresult WHERE id_student='#id')
// BEGIN
// UPDATE TABLE SET tamil = #tamil and so on... WHERE id = #id
// END
// ELSE
// BEGIN
// INSERT DATA HERE
// END
}
}
SQL Proc
CREATE PROCEDURE proc_Upd_Student
-- Add the parameters for the stored procedure here
#id VARCHAR(100),
#tamil VARCHAR(100),
#english VARCHAR(100),
#maths VARCHAR(100),
#science VARCHAR(100),
#socialscience VARCHAR(100)
AS
BEGIN
-- CHECK IF THE TABLE CONTAIN THE SAME ID
IF (SELECT COUNT(1) FROM TABLE WHERE id = #id) > 0
BEGIN
-- I DO UPDATE TO THE TABLE
UPDATE TABLE
SET Column = VALUE
WHERE id = #id
END
ELSE
BEGIN
-- IF A NEW ID ? THEN I DO INSERT, IF YOUR ID IS IDENTITY THEN YOU CAN SKIP IT NO NEED TO INSERT
INSERT INTO TABLE (COLUMN)
VALUE
(PARAM)
END
END
The store procedure above is for Update & Insert... Your Select proc can remain due to is different procedure. If you want to combine you add one more parameter called #Action

Related

Return value from stored procedure to C# function

I am trying to count how many users is updated and how many users are inserted after I run my stored procedure.
CREATE PROCEDURE [dbo].[ADProcTemp]
#Username varchar(250),
#DisplayName varchar(70),
#isEnabled tinyint,
#PassNevExp tinyint,
#addedUser int OUTPUT,
#updatedUser int OUTPUT
AS
BEGIN
SET #addedUser = 0
SET #updatedUser = 0
IF NOT EXISTS (SELECT TOP 1 PrezimeIme FROM [dbo].[tblZaposleni_AD] WITH (NOLOCK)
WHERE NetworkLogin = #Username)
BEGIN
IF(#isEnabled = 1 OR #PassNevExp = 1)
INSERT INTO [dbo].[tblZaposleni_AD](NetworkLogin, PrezimeIme, Status, PassNevExp)
VALUES (#Username, #DisplayName, #isEnabled, #PassNevExp)
SET #addedUser = #addedUser + ##ROWCOUNT;
SELECT #addedUser As UkupnoDodanihKorisnika
END
ELSE
BEGIN
UPDATE [dbo].[tblZaposleni_AD]
SET Status = #isEnabled,
PassNevExp = #PassNevExp
WHERE NetworkLogin = #Username
AND (Status <> #isEnabled) OR (PassNevExp <>#PassNevExp)
SET #updatedUser = #updatedUser + ##ROWCOUNT;
SELECT #updatedUser As UkupnoIzmjenjenihKorisnika
END
END
Here is my stored procedure and right now I want in my C# code display #addedUser and #updatedUser variable from stored procedure.
So far I create this
public void ExcStrPrc(string Username, string DisplayName, bool isEnable, bool PassNevExp)
{
SqlConnection conn = new SqlConnection(#"Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=DesignSaoOsig1;Integrated Security=True");
SqlCommand cmd = new SqlCommand("ADProcTemp", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Username", Username.ToString().Trim());
cmd.Parameters.AddWithValue("#DisplayName", DisplayName.ToString().Trim());
cmd.Parameters.AddWithValue("#isEnabled", Convert.ToInt32(isEnable));
cmd.Parameters.AddWithValue("#PassNevExp", Convert.ToInt32(PassNevExp));
cmd.Parameters.Add("#addedUser", SqlDbType.Int).Direction = ParameterDirection.Output;
cmd.Parameters.Add("#updatedUser", SqlDbType.Int).Direction = ParameterDirection.Output;
conn.Open();
int k = cmd.ExecuteNonQuery();
if (k != 0)
{
Console.WriteLine("Uspjesno izvrseno !");
}
Console.WriteLine("Ukupno novih korisnika {0}");
conn.Close();
}
Any idea how to display counter from stored procedure to C# function? I added inside my function and right now I didn't get any data in output...
TBH was a long time ago since I messed around with output parameters, but you add output parameters, but you never check those. The values you require should be in those parameters.
I suggest you try to get those values like (after the execution of course):
var addedUserCount = (int)cmd.Parameters["#addedUser"].Value;
Or something similar

Query is not checking database AdvID itself and delete

i want the query to check database AdvID itself and delete when page is loaded. Why am i getting this error call "System.Data.SqlClient.SqlException: 'Procedure or function 'DeleteByDate' expects parameter '#AdvID', which was not supplied." Shouldnt it check the database itself and delete? why do i have to supply it with AdvID? Here is my page_load code
protected void Page_Load(object sender, EventArgs e)
{
//Generate auto ID
SqlDataAdapter sad = new SqlDataAdapter("Select isnull(max(cast(AdvID as int)),0)+1 from Advertisement", sqlCon);
DataTable dt = new DataTable();
sad.Fill(dt);
advertismentIdTb.Text = dt.Rows[0][0].ToString();
//PageLoadValidations
statusTb.Text = "1";
endDateTb.Attributes["min"] = DateTime.Now.ToString("yyyy-MM-dd");
btnDelete.Enabled = false;
btnUpdate.Enabled = false;
Image1.Visible = false;
//Delete from DB Condition (EndDate)
if (sqlCon.State == ConnectionState.Closed)
sqlCon.Open();
SqlCommand sqlCmd = new SqlCommand("DeleteByDate", sqlCon);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.ExecuteNonQuery();
sqlCon.Close();
//Show GridView
FillGridView();
}
And here is my script
ALTER PROC [dbo].[DeleteByDate]
#AdvID int
AS
BEGIN
DECLARE #CurrentDate DATE = GETDATE() -- to get current date
-- Assuming that Advertisement table has the column EndDate
IF EXISTS (SELECT * FROM Advertisement a WHERE a.EndDate < #CurrentDate )
BEGIN
UPDATE a SET a.Status = 0
FROM Advertisement a
WHERE a.AdvID = #AdvID
END
END
I think you are asking for a query which will delete all advertisements that ended earlier than right now? Your current query is checking if there are any advertisements that ended before right now then deleted the one with the ID you pass in.
Based on the above assumption, try the following query:
ALTER PROC [dbo].[DeleteByDate]
AS BEGIN
UPDATE a
SET a.Status = 0
FROM Advertisement a
WHERE a.EndDate < GETDATE()
END

How to properly return count(*) values from scalar valued function

Every time I execute my code I get "false" from method
public bool exists(int vpisna, string geslo)
{
bool a = false;
Uspeh = true;
cmd = new SqlCommand("SELECT dbo.fnExists(#Vpisna,#Geslo)", povezava);
cmd.Parameters.AddWithValue("#Vpisna", vpisna);
cmd.Parameters.AddWithValue("#Geslo", geslo);
try
{
povezava.Open();
int result =(int)cmd.ExecuteScalar();
if (result==1)
{
a = true;
}
}
catch (Exception e)
{
ex = e;
}
finally
{
povezava.Close();
}
return a;
}
My scalar valued function:
[dbo].[fnExists](
#Vpisna int,
#Geslo nvarchar(40)
)
RETURNS INT AS BEGIN
DECLARE #a int
SET #a = (
SELECT
COUNT(*)
FROM
Student
WHERE
ID = #Vpisna
AND
Geslo = CONVERT( nvarchar(40), HashBytes('SHA1', #Geslo ), 2 )
)
RETURN #a
END
Everytime I get a false result, even when I try to manipulate data inside of the scalar valued function. When I try the SELECT statement on real data without a the function it works inside the SQL Management Studio.
I think your code series is wrong. Before create sql command must open sql connection or must open from sqlcommand.
Use this;
SqlConnection cnn = new SqlConnection("sql-connection-string");
cnn.Open();
SqlCommand cmd = new SqlCommand("select 1", cnn);
or
SqlConnection cnn = new SqlConnection("sql-connection-string");
SqlCommand cmd = new SqlCommand("select 1", cnn);
cmd.Connection.Open();
[dbo].[fnExists](
#Vpisna int,
#Geslo nvarchar(40)
)
RETURNS INT AS BEGIN
DECLARE #a int
SELECT
#a = COUNT(*)
FROM
Student
WHERE
ID = #Vpisna
AND
Geslo = CONVERT( nvarchar(40), HashBytes('SHA1', #Geslo ), 2 )
RETURN #a
END

returned book lending is not working in c#

I have been created student library page in aspx and c#.
I added two buttons, one for book lending on submit click and another one is return button book returning.
For example:
I enter student id and book id and click submit means, it showed the staus as 'pending'.
or
If i enter same student id and book id for returning book, it showed the status as 'returned'.
The above process works fine.
But again if enter same student id and book id for book lending menas, it doesn't work.
May i know,?
I'm new to .net., can anyone guide me?
Any help would be highly appreciated.
Thanks.
source code:
book lending:
protected void btnsub_Click(object sender, EventArgs e)
{
SqlConnection con = Connection.DBconnection();
SqlCommand com = new SqlCommand("sp_lendingstatus", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#studentid", txtstudentid.Text.Trim());
com.Parameters.AddWithValue("#bookid", txtbookid.Text.Trim());
com.Parameters.AddWithValue("#date", Calendar1.TodaysDate.Date.ToString());
com.Parameters.AddWithValue("#returndate", Calendar2.SelectedDate.ToString());
SqlParameter retval = new SqlParameter("#output", SqlDbType.VarChar, 50);
retval.Direction = ParameterDirection.Output;
com.Parameters.Add(retval);
txtstudentid.Text = string.Empty;
txtbookid.Text = string.Empty;
com.ExecuteNonQuery();
string Output = retval.Value.ToString();
output.Text = Output;
}
return:
protected void btnrtn_Click(object sender, EventArgs e)
{
SqlConnection con = Connection.DBconnection();
SqlCommand com = new SqlCommand("sp_bookreturn", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#studentid", txtstudentid.Text.Trim());
com.Parameters.AddWithValue("#bookid", txtbookid.Text.Trim());
com.Parameters.AddWithValue("#returnstatus", txtbookid.Text.Trim());
com.ExecuteNonQuery();
}
page-load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SqlConnection con = Connection.DBconnection();
{
SqlCommand com = new SqlCommand("sp_selectlendingstatus", con);
com.CommandType = CommandType.StoredProcedure;
SqlDataAdapter adp = new SqlDataAdapter(com);
DataSet ds = new DataSet();
adp.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
}
}
}
sp_selectlendingstatus:(page_load for showing status)
select *, (CASE WHEN book_lending.bookid IS NULL THEN 'Available' ELSE 'Not
Available' END) as status from studentlibrary left outer join book_lending
ON book_lending.bookid=studentlibrary.Book_id and
book_lending.returnstatus='pending'
sp_lendingstatus for book lending:
ALTER PROCEDURE sp_lendingstatus
(
#studentid int,
#output varchar(50) output,
#bookid int,
#date varchar(50),
#returndate varchar(50)
)
AS
IF NOT EXISTS (SELECT * FROM student WHERE ID=#studentid)
BEGIN
SET #output = 'student id does not exist'
END
ELSE IF NOT EXISTS (SELECT * FROM studentlibrary WHERE Book_id=#bookid)
begin
SET #output = 'Book id does not exist'
END
ELSE IF EXISTS (SELECT * FROM book_lending inner join studentlibrary ON studentlibrary.Book_id=book_lending.bookid where Book_id=#bookid)
begin
SET #output = 'Book id not available'
return
End
ELSE
BEGIN
Insert into book_lending (studentid,bookid,date,returndate) values (#studentid,#bookid,#date,#returndate)
END
book_return:
ALTER PROCEDURE sp_bookreturn
(
#returnstatus varchar(50),
#bookid int,
#studentid int
)
AS
begin
update book_lending set returnstatus='Returned' where bookid=#bookid and studentid=#studentid
End
Note: I set foreign key for bookid and studentid.
Because of this statement in your stored procedure
ELSE IF EXISTS (SELECT * FROM book_lending inner join studentlibrary ON studentlibrary.Book_id=book_lending.bookid where Book_id=#bookid)
Once a book has been checked out once, no matter if it has been returned or not, this will always have a result. You are not deleting the record of the book being lent out (good idea). Update this to exclude those records showing that the book has been returned
ELSE IF EXISTS (SELECT * FROM book_lending inner join
studentlibrary ON studentlibrary.Book_id=book_lending.bookid
Where Book_id=#bookid AND book_lending.returnstatus<>'Returned')
This update should essentially return the book to ready for lending again.

Insert, Update error: Subquery returned more than 1 row in C#

I have written a SQL script in stored procedure and query by C#.
But it throws an error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
As I know the problem is that the subquery is returning more than one row to the main query. May I know how to solve it? Thank you.
public void insertData(string TransID, string Item, string FromLocation, string Qty, string Requestor, string RefNum, string Remark, string ReasonID, string ReasonRemark, string CreateDate, string CreateUser, string ToLocation)
{
string constr = ConfigurationManager.ConnectionStrings["CIMProRPT01ConnectionString"].ConnectionString;
using (SqlConnection _cn = new SqlConnection(constr))
{
using (SqlCommand _cmd = new SqlCommand("MMSIssue_InsertOrUpdate", _cn))
{
using (SqlDataAdapter da = new SqlDataAdapter(_cmd))
{
_cn.Open();
_cmd.CommandType = CommandType.StoredProcedure;
_cmd.Parameters.AddWithValue("#INV_TRANS_ID", TransID);
_cmd.Parameters.AddWithValue("#INV_ID", Item);
_cmd.Parameters.AddWithValue("#INV_LOCATION", FromLocation);
_cmd.Parameters.AddWithValue("#INV_QTY", Qty);
_cmd.Parameters.AddWithValue("#INV_TRANS_REQUESTOR", Requestor);
_cmd.Parameters.AddWithValue("#INV_TRANS_REFNO", RefNum);
_cmd.Parameters.AddWithValue("#INV_TRANS_REMARK", Remark);
_cmd.Parameters.AddWithValue("#INV_REASON_ID", ReasonID);
_cmd.Parameters.AddWithValue("#INV_REASON_REMARK", ReasonRemark);
_cmd.Parameters.AddWithValue("#INV_CREATE_DATE", CreateDate);
_cmd.Parameters.AddWithValue("#INV_CREATE_USER", CreateUser);
_cmd.Parameters.AddWithValue("#INV_FROMLOC", ToLocation);
_cmd.Parameters.Add("#RecordFound", SqlDbType.Int, 0);
_cmd.Parameters["#RecordFound"].Direction = ParameterDirection.Output;
_cmd.ExecuteNonQuery();
string DeleteWMMRSQL = "DELETE FROM [CIMProRPT01].[dbo].[OTH_INV_QTY_LOC] WHERE INV_QTY = 0 OR INV_QTY is null OR INV_QTY <= '-1'";
SqlCommand cmd3 = new SqlCommand(DeleteWMMRSQL, _cn);
cmd3.ExecuteNonQuery();
_cn.Close();
float INV_QTY = Convert.ToInt32(_cmd.Parameters["#RecordFound"].Value.ToString());
if (INV_QTY == 2)
{
//QTY is more Than existing QTY !!");
Response.Write("QTY is more Than existing QTY !!");
Response.Redirect("MMS_LocationTrans.aspx");
}
else
{
//QTY not able to key in 0
Response.Write("QTY not able to key in 0!!");
}
}
}
}
}
Stored procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[MMSIssue_InsertOrUpdate]
#INV_TRANS_ID VARCHAR(40),
#INV_ID VARCHAR(40),
#INV_LOCATION VARCHAR(40),
#INV_QTY FLOAT,
#INV_TRANS_REQUESTOR VARCHAR(40),
#INV_TRANS_REFNO VARCHAR(40),
#INV_TRANS_REMARK VARCHAR(255),
#INV_REASON_ID VARCHAR(40),
#INV_REASON_REMARK VARCHAR(255),
#INV_CREATE_DATE DATETIME,
#INV_CREATE_USER VARCHAR (255),
#INV_FROMLOC VARCHAR (40),
#RecordFound INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT * FROM OTH_INV_QTY_LOC
WHERE INV_ID = #INV_ID AND INV_LOCATION = #INV_LOCATION)
BEGIN
UPDATE OTH_INV_QTY_LOC
SET [INV_ID] = #INV_ID,
INV_LOCATION = #INV_LOCATION,
INV_QTY = INV_QTY - #INV_QTY
WHERE INV_ID = #INV_ID
AND INV_LOCATION = #INV_LOCATION
INSERT INTO OTH_INV_TRANSACTION (INV_TRANS_ID, INV_ID, INV_TRANS_LOCATION, INV_TRANS_QTY, INV_TRANS_REQUESTOR, INV_TRANS_REFNO, INV_TRANS_REMARK, INV_REASON_ID, INV_REASON_REMARK, INV_CREATE_DATE, INV_CREATE_USER, INV_FROMLOC)
VALUES (#INV_TRANS_ID, #INV_ID, #INV_LOCATION, #INV_QTY, #INV_TRANS_REQUESTOR, #INV_TRANS_REFNO, #INV_TRANS_REMARK, #INV_REASON_ID, #INV_REASON_REMARK, #INV_CREATE_DATE, #INV_CREATE_USER, #INV_FROMLOC)
DECLARE #InvFindQTY FLOAT
SET #InvFindQTY = (SELECT INV_QTY FROM OTH_INV_QTY_LOC)
IF #InvFindQTY >= #INV_QTY
BEGIN
SELECT #RecordFound = 2
END
ELSE
BEGIN
SELECT #RecordFound = 1
END
END
ELSE
BEGIN
SELECT #RecordFound = 0
END
END
The issue is with this line in the stored procedure:
DECLARE #InvFindQTY FLOAT
SET #InvFindQTY = ( SELECT INV_QTY FROM OTH_INV_QTY_LOC)
If you have more than one record in OTH_INV_QTY_LOC, you will receive this error.
It looks like you should be able to fix the problem by adding
WHERE INV_ID = #INV_ID
to ensure that only a single record is selected, i.e.:
SET #InvFindQTY = ( SELECT INV_QTY FROM OTH_INV_QTY_LOC WHERE INV_ID = #INV_ID)

Categories

Resources