Display id after insert in stored procedure [duplicate] - c#

This question already has answers here:
How to get last inserted id?
(16 answers)
Closed 5 years ago.
How to display the id after inserting the data with the use of stored procedure, my sample stored procedure is like this..
CREATE PROCEDURE [dbo].[insertResidence]
#Fname varchar(50),
#Lname varchar(50),
#Mname varchar(50),
#Bdate varchar(50),
#BirthPlace varchar(50),
#CivStat varchar(50),
#Purok varchar(50),
#Religion varchar(50),
#Gender varchar(50),
#CitShip varchar(50)
AS
Begin tran one;
Declare #resId INT;
INSERT INTO [tbl_Residence] (resFname, resLname, resMname, resBdate, resBirthPlace, resGender) VALUES (#Fname,#Lname,#Mname,#Bdate,#BirthPlace,#Gender);
Select #resId = SCOPE_IDENTITY();
NSERT INTO [tbl_Religion] (resId, religion) VALUES (#resId,#Religion);
INSERT INTO [tbl_Purok] (resId,pur_sit) VALUES (#resId,#Purok);
INSERT INTO [tbl_Citizenship] (resId,citship) VALUES (#resID,#Purok);
Select resId from tbl_Residence WHERE resId = #resId;
commit tran;
RETURN
After inserting the data I want to display the id in the label or textboxt.
I use ExecuteNonQuery() in the transaction..
This is the code of inserting data in transaction
public int insertRes(Informations info)
{
//Insert Residence Informations
SqlCommand cmd = new SqlCommand("InsertResidence");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#FName", SqlDbType.VarChar).Value = info.Fname;
cmd.Parameters.AddWithValue("#LName", SqlDbType.VarChar).Value = info.Lname;
cmd.Parameters.AddWithValue("#MName", SqlDbType.VarChar).Value = info.Mname;
cmd.Parameters.AddWithValue("#BDate", SqlDbType.VarChar).Value = info.Bdate;
cmd.Parameters.AddWithValue("#BirthPlace", SqlDbType.VarChar).Value = info.BirthPlace;
cmd.Parameters.AddWithValue("#CivStat", SqlDbType.VarChar).Value = info.CivStat;
cmd.Parameters.AddWithValue("#Purok", SqlDbType.VarChar).Value = info.purok;
cmd.Parameters.AddWithValue("#Religion", SqlDbType.VarChar).Value = info.Religion;
cmd.Parameters.AddWithValue("#Gender", SqlDbType.VarChar).Value = info.Gender;
cmd.Parameters.AddWithValue("#CitShip", SqlDbType.VarChar).Value = info.CitShip;
return db.ExeNonQuery(cmd);
}
UI layer :
Business layer:

ExecuteNonQuery will only return you the number of rows effected by your command.
Use ExecuteScalar, which will return you resId.
To display:
int resId = (int)cmd.ExecuteScalar();
Then in your UI:
lblMyLabel.Text = resId.ToString();

Related

Why i can not handle the store procedure return value is c#?

I'm new in c#,and want to write simple application work with sql server store procedure,in the sql server write this store procedure:
USE [mammutRecruitment]
ALTER PROCEDURE [dbo].[FirstStep]
#Name nvarchar(max),#Family nvarchar(max),#FatherName nvarchar(max),#BirthCertificate bigint,#PlaceOfBirth nvarchar(max),#BirthDate datetime,
#NationalCode bigint,#Religion nvarchar(max),#faith nvarchar(max),#Nationality nvarchar(max),#BloodGroup nvarchar(max)
AS
BEGIN
DECLARE #MYID bigint
insert into [dbo].[UserMainSpecifications] values(#Name,#Family,#FatherName,#BirthCertificate,#PlaceOfBirth,1,#BirthDate,#NationalCode,
#Religion,#faith,#Nationality,#BloodGroup,12,'123','123',1,2015-1-1,'12','123','1234',1)
select #MYID=[UserID] from [mammutRecruitment].[dbo].[UserMainSpecifications]
where [NationalCode]=#NationalCode
select #MYID as myID
END
and in c# write this code for call that:
using (SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=mammutRecruitment;Integrated Security=True"))
{
using (SqlCommand cmd = new SqlCommand("FirstStep", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = m.Name;
cmd.Parameters.Add("#Family", SqlDbType.NVarChar).Value = m.Family;
cmd.Parameters.Add("#FatherName", SqlDbType.NVarChar).Value = m.FatherName;
cmd.Parameters.Add("#BirthCertificate", SqlDbType.BigInt).Value =Convert.ToInt64(m.BirthCertificate);
cmd.Parameters.Add("#PlaceOfBirth", SqlDbType.NVarChar).Value = m.PlaceOfBirth;
cmd.Parameters.Add("#BirthDate", SqlDbType.DateTime).Value =Convert.ToDateTime(dt.ToString());
cmd.Parameters.Add("#NationalCode", SqlDbType.BigInt).Value =Convert.ToInt64(m.NationalCode);
cmd.Parameters.Add("#Religion", SqlDbType.NVarChar).Value = m.Religion;
cmd.Parameters.Add("#faith", SqlDbType.NVarChar).Value = m.faith;
cmd.Parameters.Add("#Nationality", SqlDbType.NVarChar).Value = m.Nationality;
cmd.Parameters.Add("#BloodGroup", SqlDbType.NVarChar).Value = m.BloodGroup;
SqlParameter retval = cmd.Parameters.Add("#myID", SqlDbType.BigInt);
retval.Direction = ParameterDirection.ReturnValue;
con.Open();
cmd.ExecuteNonQuery();
var retunvalue = cmd.Parameters["#myID"].Value;
but in the this line i get zero value always:
var retunvalue = cmd.Parameters["#myID"].Value;
What happen?How can i solve that problem?thanks.
This line:
cmd.ExecuteNonQuery();
Is executing your query and not returning a value.
You could start by looking into using this instead:
cmd.ExecuteReader();
Or if you want the value of the first field of the first row, you could use this:
var returnValue = cmd.ExecuteScalar();
Which will give you an object that you can then convert or cast into the appropriate type for your method.
SqlCommand.ExecuteNonQuery Method ()
Executes a Transact-SQL statement against the connection and returns
the number of rows affected.
SqlCommand.ExecuteScalar Method ()
Executes the query, and returns the first column of the first row in
the result set returned by the query. Additional columns or rows are
ignored.
I believe you want the second method
You need to include #myID as an output parameter in your stored procedure definition:
ALTER PROCEDURE [dbo].[FirstStep]
#Name nvarchar(max),#Family nvarchar(max),#FatherName nvarchar(max),#BirthCertificate bigint,#PlaceOfBirth nvarchar(max),#BirthDate datetime,
#NationalCode bigint,#Religion nvarchar(max),#faith nvarchar(max),#Nationality nvarchar(max),#BloodGroup nvarchar(max)
, #myID bigint output
AS
And then remove the line
DECLARE #MYID bigint
You also need to add the parameter to cmd in your c# code:
cmd.Parameters.Add(retval);
you need define #MYID as output parameter.
USE [mammutRecruitment]
ALTER PROCEDURE [dbo].[FirstStep]
#MYID bigint output,#Name nvarchar(max),#Family nvarchar(max),#FatherName nvarchar(max),#BirthCertificate bigint,#PlaceOfBirth nvarchar(max),#BirthDate datetime,
#NationalCode bigint,#Religion nvarchar(max),#faith nvarchar(max),#Nationality nvarchar(max),#BloodGroup nvarchar(max)
AS
BEGIN
insert into [dbo].[UserMainSpecifications] values(#Name,#Family,#FatherName,#BirthCertificate,#PlaceOfBirth,1,#BirthDate,#NationalCode,
#Religion,#faith,#Nationality,#BloodGroup,12,'123','123',1,2015-1-1,'12','123','1234',1)
select #MYID = SCOPE_IDENTITY()
END
and add your command
SqlParameter pOut = new SqlParameter("#MYID", SqlDbType.BigInt);
pOut.Direction = ParameterDirection.Output;
cmd.Parameters.Add(pOut);
You can read the value now
cmd.ExecuteNonQuery();
long newId = (long)pOut.Value;
Actually, you need change that statement:
retval.Direction = ParameterDirection.ReturnValue;
to
retval.Direction = ParameterDirection.Output
because ExecuteNonQuery return:
Executes a Transact-SQL statement against the connection and returns the number of rows affected.
Although the ExecuteNonQuery returns no rows, any output parameters or return values mapped to parameters are populated with data.
End include your parameter to procedure definition:
#myID BIGINT OUTPUT
USE [mammutRecruitment]
ALTER PROCEDURE [dbo].[Firststep] #Name NVARCHAR(max),
#Family NVARCHAR(max),
#FatherName NVARCHAR(max),
#BirthCertificate BIGINT,
#PlaceOfBirth NVARCHAR(max),
#BirthDate DATETIME,
#NationalCode BIGINT,
#Religion NVARCHAR(max),
#faith NVARCHAR(max),
#Nationality NVARCHAR(max),
#BloodGroup NVARCHAR(max),
#myID BIGINT output
AS
BEGIN
INSERT INTO [dbo].[usermainspecifications]
VALUES (#Name,
#Family,
#FatherName,
#BirthCertificate,
#PlaceOfBirth,
1,
#BirthDate,
#NationalCode,
#Religion,
#faith,
#Nationality,
#BloodGroup,
12,
'123',
'123',
1,
2015 - 1 - 1,
'12',
'123',
'1234',
1)
SELECT #myID = [userid]
FROM [mammutRecruitment].[dbo].[usermainspecifications]
WHERE [nationalcode] = #NationalCode
END

Stored procedure MERGE (INSERT OR UPDATE) and return ID issue

So I'm trying to learn how to use stored procedures and for the most part I somewhat understand how to use them except for this merge procedure.
What I'm trying to do is use the MERGE procedure to Insert if a row does not already exist and return the ID ELSE IF NOT EXISTS then just return the ID.
Here is currently what I have so far.
CREATE PROCEDURE dbo.authors_InsertOrUpdate
-- Add the parameters for the stored procedure here
#FirstName nvarchar(50),
#LastName nvarchar(50),
#id int = NULL OUTPUT
AS
MERGE Authors AS target
USING (SELECT #FirstName, #LastName) AS source (FirstName, LastName)
ON target.FirstName = source.FirstName AND target.LastName = source.LastName
WHEN MATCHED THEN
UPDATE
SET #id = SCOPE_IDENTITY()
WHEN NOT MATCHED THEN INSERT
(FirstName, LastName) VALUES (source.FirstName, source.LastName);
SET #id = SCOPE_IDENTITY()
Everything works fine as far as inputting the values/information into the database and finding an existing one but I'm not getting my ID value back correctly. Here is my method that uses it..
private static int storeAuthors(string firstName, string lastName)
{
String commandText = "dbo.authors_InsertOrUpdate";
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["AmazonCrawler.Properties.Settings.database"].ToString()))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#FirstName", firstName));
command.Parameters.Add(new SqlParameter("#LastName", lastName));
SqlParameter authorId = new SqlParameter("#id", SqlDbType.Int);
authorId.Direction = ParameterDirection.Output;
command.Parameters.Add(authorId);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
return Convert.ToInt32(authorId.Value);
}
}
}
Please help me fix this!
Thanks in advance.
---------EDIT------------
Updated the procedure to this yet I'm still receiving a null value in my code when i try to return the value
CREATE PROCEDURE dbo.authors_InsertOrUpdate
-- Add the parameters for the stored procedure here
#FirstName nvarchar(50),
#LastName nvarchar(50),
#id int OUTPUT
AS
MERGE Authors AS target
USING (SELECT #id, #FirstName, #LastName) AS source (id, FirstName, LastName)
ON target.FirstName = source.FirstName AND target.LastName = source.LastName
WHEN NOT MATCHED THEN
INSERT (FirstName, LastName) VALUES (source.FirstName, source.LastName);
SET #id = SCOPE_IDENTITY()
Edit reference 1
Edit reference 2
Edit reference 3
ALTER PROCEDURE dbo.authors_InsertOrUpdate
-- Add the parameters for the stored procedure here
#FirstName nvarchar(50),
#LastName nvarchar(50),
#id int OUTPUT
AS
MERGE Authors AS target
USING (SELECT #id, #FirstName, #LastName) AS source (ID, FirstName, LastName)
ON target.FirstName = source.FirstName AND target.LastName = source.LastName
WHEN MATCHED THEN
UPDATE SET #id = target.ID
WHEN NOT MATCHED THEN
INSERT (FirstName, LastName) VALUES (source.FirstName, source.LastName);
SET #id = SCOPE_IDENTITY()
SELECT #id
Still receiving same error listed in reference 2.
=( no solution yet.
here is my passed in values with a return of zero as an id
and here is my database
Edit reference 4
Tried changing my parameters when putting in the values to this as I thought perhaps closing it before getting the value was causing the problem but no luck
private static int storeAuthors(string firstName, string lastName)
{
String commandText = "dbo.authors_InsertOrUpdate";
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["AmazonCrawler.Properties.Settings.database"].ToString()))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#FirstName", firstName));
command.Parameters.Add(new SqlParameter("#LastName", lastName));
SqlParameter authorId = new SqlParameter("#id", SqlDbType.Int);
authorId.Direction = ParameterDirection.Output;
command.Parameters.Add(authorId);
connection.Open();
command.ExecuteNonQuery();
int value = Convert.ToInt32(authorId.Value);
connection.Close();
return value;
}
}
}
In the UPDATE case, you aren't generating a new IDENTITY, you are just querying, so SCOPE_IDENTITY() won't return the right value. In the UPDATE case, SCOPE_IDENTITY() may appear to work, at first, but it is actually returning the value from the last INSERT in scope (I think), which could be the last execution of the stored proc.
I recommend using the OUTPUT clause. I tried to make something work with your approach, and with #usr's suggestion as well, but the only thing I could make work was to use the OUTPUT clause. See below:
CREATE PROCEDURE dbo.authors_InsertOrUpdate
-- Add the parameters for the stored procedure here
#FirstName nvarchar(50),
#LastName nvarchar(50),
#id int OUTPUT
AS BEGIN
DECLARE #MergeOutput table
(
ACTION VARCHAR(10),
ID INT
);
MERGE Authors AS target
USING (SELECT #id, #FirstName, #LastName) AS source (id, FirstName, LastName)
ON target.FirstName = source.FirstName AND target.LastName = source.LastName
WHEN NOT MATCHED THEN
INSERT (FirstName, LastName) VALUES (source.FirstName, source.LastName)
WHEN MATCHED THEN UPDATE
SET #Id = target.Id
OUTPUT $action, INSERTED.ID INTO #MergeOutput;
SELECT #Id = Id FROM #MergeOutput
END
GO
DECLARE #id2 INT
exec dbo.authors_InsertOrUpdate 'Melvin', 'Smith', #id = #id2 OUTPUT
SELECT #id2
GO
I tried to make something work using SCOPE_IDENTITY(), and using SET #Id = target.Id as in #usr's answer but I kept getting the last inserted value returned, even for an update.
SELECT * INTO #o FROM sys.objects
DECLARE #id INT
MERGE #o AS target
USING (SELECT OBJECT_ID('tempdb..#o') AS object_id) AS source (object_id)
ON target.object_id = source.object_id
WHEN MATCHED THEN UPDATE SET #id = target.object_id;
SELECT #id
You can use columns of the MERGE query pretty freely. It is a very powerful statement.

C# stored procedure error returning value [duplicate]

This question already has answers here:
Return Value from a Stored Procedure
(2 answers)
Closed 8 years ago.
I never worked with a stored procedure that returned a value in C#. I tried looking on the internet and I haven't found anything that helps. It probably because I really don't understand how it works.
STORED PROCEDURE - dbo.sp_Admin_AddNewUser
USE [NGE]
GO
/****** Object: StoredProcedure [dbo].[sp_Admin_AddNewUser] Script Date: 05/19/2014 15:07:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_Admin_AddNewUser]
(
#firstname varchar(50),
#lastname varchar(50),
#middlename varchar(50),
#phone_office varchar(50),
#retval varchar(50) OUTPUT
)
AS
INSERT INTO EDUSER
(firstname,
lastname,
middlename,
phone_office,
synceratorInactiveFlag)
VALUES(
rtrim(ltrim(#firstname)),
rtrim(ltrim(#lastname)),
rtrim(ltrim(#middlename)),
rtrim(ltrim(#phone_office)),
'A')
IF ##error = 0
SELECT #retval = rtrim(ltrim(SCOPE_IDENTITY()))
--Add the user to the group
IF EXISTS (SELECT 1 FROM EDGROUP WHERE [group_id] = #GroupID)
BEGIN
INSERT INTO [NGE].[dbo].[EDGROUPPRACTICE]
([group_id]
,[user_id])
VALUES
(#GroupID
,#retval)
END
Code to call the store procedure:
SqlCommand cmd = new SqlCommand("dbo.sp_Admin_AddNewUser", conn);
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
cmd.Parameters.Add(new SqlParameter("#firstname","Test"));
cmd.Parameters.Add(new SqlParameter("#lastname", "User"));
cmd.Parameters.Add(new SqlParameter("#middlename", "M"));
cmd.Parameters.Add(new SqlParameter("#phone_office", "(555) 555-5555"));
cmd.Parameters.Add("#retval", "");
cmd.Parameters["#retval"].Direction = ParameterDirection.ReturnValue;
cmd.ExecuteNonQuery();
tempUserID = (string)cmd.Parameters["#retval"].Value; //GET ERROR HERE
I get an error:
Procedure or function expects parameter '#retval' which was not supplied
Try to add the parameters this way:
SqlParameter firstName = cmd.Parameters.Add("#firstname", SqlDbType.VarChar, 50);
nikParam.Direction = ParameterDirection.Input;
//Rest of the params
//Then the output param
SqlParameter retValOutput = cmd.Parameters.Add("#retval", SqlDbType.VarChar, 50);
nikParam.Direction = ParameterDirection.Output;
I hope this helps ;)
It is not return value, it is just output parameter. Use
cmd.Parameters["#retval"].Direction = ParameterDirection.Output;
instead of
cmd.Parameters["#retval"].Direction = ParameterDirection.ReturnValue;
To have return value you must do
RETURN #retval
in your SP.

Could not insert complete values into database using stored procedure?

I'm very new to using stored procedure in C#. But m unable to insert the values into database completely?
create procedure insertPro
(#name as varchar,
#lname as varchar,
#phone as varchar)
as
insert into std_info
values (#name, #lname, #phone)
go
And here is my C# code
SqlConnection con = new SqlConnection("Data Source=xxxxxxxx;Integrated Security=SSPI;Initial Catalog=xxxxx");
SqlCommand cmd = new SqlCommand("insertPro",con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#name", SqlDbType.VarChar).Value = textBox1.Text;
cmd.Parameters.Add("#lname", SqlDbType.VarChar).Value = textBox2.Text;
cmd.Parameters.Add("#phone", SqlDbType.VarChar).Value = textBox3.Text;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
This insert values into database but not completely for example, if i insert first name as abc then it only insert a and same for the last name and phone?
Put a length on your parameters:
create procedure insertPro(
#name as varchar(30),
#lname as varchar(30),
#phone as varchar(30)
Change your stored procedure to:
create procedure insertPro
(
#name as varchar(max), //change (max) to maximum constraint length you set for each column
#lname as varchar(max),
#phone as varchar(max)
)
as
insert into std_info values (#name,#lname,#phone)
#name as varchar
So using simple varchar without any length specified. It takes only single character. So that's why you are seeing only one character in your table. You just need to specify them with length equal to length of the column.
#name as varchar(100)

How to save data in a table with multiple foreign keys while using a stored procedure in C#

I have a table Item_Order with the columns
orderId, clintName, companyName, itemName, orderDate, qauntity, clintId_FK, itemId_FK, status
where clintId_FK and item_FK are the primary keys of the Clint and Item_Configuration tables, respectively.
I have created a stored procedure for an insert record in the Item_Order table. i.e.
ALTER PROCEDURE [dbo].[Order_Create_SP]
#orderId varchar(50),
#clintName varchar(50),
#companyName varchar(50),
#itemName varchar(50),
#orderDate datetime,
#qauntity int,
#status char(10),
#operation int
AS
DECLARE #id1 varchar(50)
DECLARE #id2 varchar(50)
BEGIN
SET NOCOUNT ON;
if #operation = 0
BEGIN
SELECT top(1)#id1 = clintId FROM dbo.Clint order by clintId desc
select top(1)#id2 = itemId from dbo.Item_Configuration order by itemId desc
insert into Item_Order(orderId, clintName, companyName, itemName, orderDate, qauntity, clintId_FK, itemId_FK, status)
values(#orderId, #clintName, #companyName, #itemName, #orderDate, #qauntity, #id1, #id2, 'OPEN')
END
END
and my C# code is
private void btnOrder_Click(object sender, EventArgs e)
{
SqlConnection conn1 = new SqlConnection();
try
{
SqlCommand inserOrder= new SqlCommand("Order_Create_SP", conn1);
inserOrder.CommandType = CommandType.StoredProcedure;
inserOrder.Parameters.Add("#orderId", SqlDbType.VarChar);
inserOrder.Parameters["#orderId"].Value = oredrId.Text;
inserOrder.Parameters.Add("#clintName", SqlDbType.VarChar);
inserOrder.Parameters["#clintName"].Value = comboClint.Text;
inserOrder.Parameters.Add("#itemName", SqlDbType.VarChar);
inserOrder.Parameters["#itemName"].Value = comboItem.Text;
inserOrder.Parameters.Add("#orderDate", SqlDbType.DateTime);
inserOrder.Parameters["#orderDate"].Value=Convert.ToDateTime(orderDate.Text);
inserOrder.Parameters.Add("#qauntity", SqlDbType.Int);
inserOrder.Parameters["#qauntity"].Value = Convert.ToInt32(qauntity.Text);
inserOrder.Parameters.Add("#stauts", SqlDbType.VarChar);
inserOrder.Parameters["#stauts"].Value = "OPEN";
inserOrder.Parameters.Add("#companyName", SqlDbType.VarChar);
inserOrder.Parameters["#companyName"].Value = companyName.Text;
inserOrder.Parameters.Add("#operation", SqlDbType.VarChar);
inserOrder.Parameters["#operation"].Value = 0;
inserOrder.ExecuteNonQuery();
I am doing something that is not compatible? It is not working properly. Please help.
Thank you.
Not sure if this is your problem or not, but your stored procedure is missing WHERE clauses when looking up the foreign keys. Try changing to something like
SELECT top(1)#id1 = clintId FROM dbo.Clint WHERE Name = #clintName order by clintId desc
SELECT top(1)#id2 = itemId from dbo.Item_Configuration WHERE name = #itemName order by itemId desc

Categories