I am creating a web application using ASP.net C#. I have a booking form and I need to insert data into a table using a Stored Procedure. The table has several columns, out of which second column is a computed column. The Stored Procedure is set up to insert the data and fetch the value from the second column after insert. Below is the code for Stored Procedure:
Create Procedure sp_InsertCashPooja
#FirstName varchar(100),
#LastName varchar(100),
#TelNo bigint,
#Star char(50),
#Rasi char(50),
#Gothram char(50),
#PDMID int,
#PayMode bit,
#PujaName char(50),
#DonateAmt decimal(19,2),
#RcptNo varchar(25) output
as
Begin
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION
if #PujaName != 'DONATION'
Begin
INSERT INTO PoojaDetails (FirstName, LastName, TelNo, Star, Rasi, Gothram, PoojaDietyMasterID, PayMode) values (#FirstName,#LastName,#TelNo,#Star,#Rasi,#Gothram,#PDMID,#PayMode)
End
if #PujaName = 'DONATION'
Begin
DECLARE #isDonate int = 0;
INSERT INTO PoojaDetails (FirstName, LastName, TelNo, Star, Rasi, Gothram, PoojaDietyMasterID, PayMode, isDonate, DonateAmount) values (#FirstName,#LastName,#TelNo,#Star,#Rasi,#Gothram,#PDMID,#PayMode, #isDonate, #DonateAmt)
End
Select #RcptNo = max(ReceiptNo) from PoojaDetails
Return #RcptNo
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
ROLLBACK TRANSACTION
END CATCH
SET NOCOUNT OFF;
End
I would like to insert data on the click of a button: I was able to figure out the below code....
protected void btnSave_Click(object sender, EventArgs e)
{
frmFirstName = txtFirstName.Text.Trim().ToUpper();
frmLastName = txtLastName.Text.Trim().ToUpper();
frmPhoneNo = Convert.ToInt32(txtPhoneNo.Text.Trim());
frmNakshatra = Convert.ToString(cmbNakshatra.SelectedItem).Trim();
frmRasi = Convert.ToString(cmbRasi.SelectedItem).Trim();
frmGothram = Convert.ToString(cmbGothram.SelectedItem).Trim();
frmPujaName = Convert.ToString(cmbPujaName.SelectedItem).Trim();
using (SqlConnection connection = new SqlConnection())
{
if (frmPayMode == "Cash")
{
if (frmPujaName == "DONATION")
{
SqlDataAdapter CashAdapter = new SqlDataAdapter();
CashAdapter.InsertCommand = new SqlCommand("sp_InsertCashPooja", connection);
CashAdapter.InsertCommand.CommandType = CommandType.StoredProcedure;
Please help.... I want to capture the returning RcptNo and later intend to call another ASPX page and pass the value using a Query String.
Thanks
Use simple SqlCommand for calling your SP
connection.Open();
var cmd = new SqlCommand("sp_InsertCashPooja", connection);
cmd.Parameters.AddWithValue("FirstName", frmFirstName);
// Add all the others parameters in same way
var id = (int)cmd.ExecuteScalar();
connection.Close();
Change the return variable to:
Select #RcptNo = SCOPE_IDENTITY()
It will return the identity number created for the inserted record within this procedure.
use sql parameter..
connection = ConfigurationManager.AppSettings["mycon"];
SqlParameter[] para = new SqlParameter[2];
para[0] = new SqlParameter("#stored procedure column name", string name);
para[1] = new SqlParameter("#stored procedure column name", string name);
Related
I have a stored procedure in which I want to get the last inserted row for a specific table say table TbUsers , so in the end of it, I type that line:
select IDENT_CURRENT('TbUsers')
Now I want to get that result in C#, using SqlCommand; I pass these parameters to to the stored procedure:
SqlCommand command = new SqlCommand("InsertUsers", conn);
command.CommandType = System.Data.CommandType.StoredProcedure;
/* Insert in TbUsager */
SqlParameter[] parameters = new SqlParameter[]
{
new SqlParameter("#firstName" ,value.firstname),
new SqlParameter("#lastName",value.lastname),
new SqlParameter("#email",value.email),
new SqlParameter("#phoneNumber",value.phoneNumber),
new SqlParameter("#address",value.address),
new SqlParameter("#country",value.country),
new SqlParameter("#city",value.city),
new SqlParameter("#zipCode",value.zip_code)
};
command.Parameters.AddRange(parameters);
var rdr = command.ExecuteReader()
How can I get the returned result of the stored procedure?
Update
i have added this code :
// command.Parameters.AddRange(parameters);
var LastInsertedUsagerId = new SqlParameter("#lastInsertedUsagerId", System.Data.SqlDbType.Int);
LastInsertedUsagerId.Direction = ParameterDirection.Output;
command.Parameters.Add(LastInsertedUsagerId);
// var rdr = command.ExecuteReader();
var LastInsertedUsagerId2 = command.Parameters["#LastInsertedUsagerId"].Value;
but i still getting null as a result ?
Update2
this is my SP:
ALTER PROCEDURE [dbo].[InsertUsager]
-- Add the parameters for the stored procedure here
#Nom_Usager varchar(20),
#Prenom_Usager varchar(20),
#Email_Usager varchar(20),
#Telephone_Portable_Usager varchar(20),
#Adresse_Usager varchar(20),
#Pays_Usager varchar(20),
#Ville_Usager varchar(20),
#IdVille_Usager varchar(20),
#LastInserted_IdUsager int OUTPUT
AS
BEGIN
-- Insert a new usager
declare #IdinsertedUsager table(IdinsertedUsager int)
declare #IdAddressVillePayselse table(IdAddressVillePayselse int)
declare #newUsager int , #IdAddressVillePays int , #addressvp int,#IdCountry int,#IdVille int
Insert into TbUsager (IdTypeUsager,Nom_Usager,Prenom_Usager,Indic_Maj)
Output inserted.IdUsager into #IdinsertedUsager
values(1,#Prenom_Usager,#Nom_Usager,'P')
SELECT #newUsager = IdinsertedUsager FROM #IdinsertedUsager
/* some code */
select #LastInserted_IdUsager=IDENT_CURRENT('TbUsers')
END
and it works well when i execute it in sqlserver
Assuming you're returning the identity id correctly(as output parameter) in your SP, in your C# code you can retrieve it like this:
var id = command.Parameters["#id"].Value;
Change #id to the name of your output variable in SP.
Here's a link to see how to do it correctly in detail:
https://www.aspsnippets.com/Articles/Return-Identity-value-from-Stored-Procedure-in-SQL-Server.aspx
Solved, in addition to #Siavash is answer , in order to work we need to use : command.ExecuteNonQuery()
instead of command.ExecuteReader()
In this documentation we get the difference and when to use each one.
I have a stored procedure called lastID like this:
CREATE PROCEDURE lastID(#id varchar(64) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #f VARCHAR(64);
SELECT TOP 1 #f = work_id
FROM workorder
WHERE (RIGHT(work_id,2)) = (RIGHT(Year(getDate()),2))
ORDER BY work_id DESC;
IF(#f IS NULL)
BEGIN
SET #f = 'No work orders';
SET #id = #f;
RETURN #id;
END
ELSE
BEGIN
SET #id = #f;
RETURN #id;
END
END
This stored procedure returns the last id from the table workorder, now I'm trying to execute this procedure in C#, this is the code:
private void lastWorkId()
{
String strConnString = "Server=.\\SQLEXPRESS;Database=recalls;Integrated Security=true";
SqlConnection con = new SqlConnection(strConnString);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "lastID";
cmd.Parameters.Add("#id", SqlDbType.VarChar, 64).Direction = ParameterDirection.Output;
cmd.Connection = con;
try
{
con.Open();
cmd.ExecuteNonQuery();
String id = cmd.Parameters["#id"].Value.ToString();
lastid.Text = id.ToString(); //Putting the return value into a label
}
catch (Exception ex)
{
throw ex;
}
finally
{
con.Close();
con.Dispose();
}
}
I don't know what are wrong with my code, because an exception is displayed, and this says
Conversion failed when converting the varchar value ' OT- 003-16 ' to data type int
I was wrong about my first answer, here is the updated answer:
Your stored procedure is setup with an OUTPUT parameter of type VARCHAR(64).
Within your proc you have a couple of RETURN #id; statements, which is actually returning a VARCHAR(64). You only need to set your OUTPUT variable within the stored procedure. The RETURN statement expects an integer expression. Here's the updated fixed sproc using OUTPUT appropriately:
ALTER PROCEDURE [dbo].[lastID](#id varchar(64) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #f VARCHAR(64);
SELECT TOP 1 #f = work_id FROM workorder WHERE (RIGHT(work_id,2)) = (RIGHT(Year(getDate()),2)) ORDER BY work_id DESC;
IF(#f IS NULL)
BEGIN
SET #f = 'No work orders';
SET #id = #f;
END
ELSE
BEGIN
SET #id = #f;
END
END
Error is basically should get fixed by cast
((RIGHT(work_id,2)) as int)
But code can be further condensed and improved.
CREATE PROCEDURE lastID(#id varchar(64) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
SELECT TOP 1 #id = isnull(work_id , 'No work orders') FROM workorder WHERE cast ((RIGHT(work_id,2)) as int)= (RIGHT(Year(getDate()),2)) ORDER BY work_id DESC;
RETURN #id;
END
MySql Procedure Code:
CREATE DEFINER=`root`#`localhost` PROCEDURE `USP_CreateCliente`(IN nome_cliente VARCHAR(45))
BEGIN
Select 20;
INSERT INTO clienti ( nome_cliente )
VALUES ( nome_cliente );
Select id_cliente from clienti;
END
C# code in the controller page:
ClienteInfo CI = new ClienteInfo();
DboUser objdbo = new DboUser();
int id_cliente = 0;
CI.nome_cliente = txtNomeCliente.Text;
id_cliente = objdbo.CreateClienteInfo(CI);
DboUser class:
public int CreateClienteInfo(ClienteInfo CI)
{
int result;
MySqlConnection conn = new MySqlConnection();
DbConnection db = new DbConnection();
conn = db.ConnessioneDb();
MySqlCommand cmd = new MySqlCommand(Costanti.StoredProcedures.USP_CreateCliente, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#nome_cliente", CI.nome_cliente);
result = cmd.ExecuteNonQuery();
conn.Close();
return result;
}
I want my C# code to retrieve the id of my customer after inserting it into the database, so I can save it to the session and retrieve it again later in a page that will print a document with the customer's informations.
My id_cliente returns 0, do you notice any syntax error?
Did I do something wrong?
I'm 90% sure it's a problem dealing with the stored precedure tough, cause the customer is inserted correctly
Change this line
result = cmd.ExecuteNonQuery();
to
result = Convert.ToInt32(cmd.ExecuteScalar());
but you should also change your stored procedure because it doesn't return the last id generated for you by the AUTO_INCREMENT column id_cliente
CREATE DEFINER=`root`#`localhost` PROCEDURE `USP_CreateCliente`(IN nome_cliente VARCHAR(45))
BEGIN
INSERT INTO clienti ( nome_cliente ) VALUES ( nome_cliente );
Select LAST_INSERT_ID();
END
In MySql, to get the generated auto_increment value, you could use LAST_INSERT_ID(), next, your C# code don't need to use ExecuteNonQuery, which returns just the number of rows that you have changed, added or deleted, but you use ExecuteScalar which returns the first column of the first row of the last SELECT command executed by your stored procedure. (It is the SELECT LAST_INSERT_ID())
Also, to complete the answer, you don't really need a stored procedure for this kind of simple work. The advantages should be minimal while the problems related to a different piece of software to maintain are self evident.
Your C# code could be (removed the usage of your DbConnection class because it is not clear what it does)
public int CreateClienteInfo(ClienteInfo CI)
{
int result;
string cmdText = #"INSERT INTO clienti ( nome_cliente ) VALUES ( nome_cliente );
Select LAST_INSERT_ID();";
using(MySqlConnection conn = new MySqlConnection(....connectionstring .....))
using(MySqlCommand cmd = new MySqlCommand(cmdText, conn);
{
conn.Open()
cmd.Parameters.AddWithValue("#nome_cliente", CI.nome_cliente);
result = Convert.ToInt32(cmd.ExecuteScalar())
return result;
}
}
Here you use the possibility to pass batch commands to your MySql engine, meaning two commandtexts with the same MySqlCommand separating them with the semicolon
I'm trying to call the below stored procedure but I am unsure on what to pass through one of the parameters (#UnsubscribeTypes) I've tried passing in a list but got a compile error. I'm using c#, Visual Studio 2010, web forms. Any ideas on what I should pass in when calling the stored procedure in my c# code (ado.net)?
Here is my stored procedure:
ALTER PROCEDURE [czone].[SetAccountEmailPreference]
(
#EmailAddress VARCHAR(255),
#UnsubscribeTypes dbo.ListOfIDs READONLY,
#SentEmailID INT = NULL
)
AS
SET NOCOUNT ON;
EXEC dbo.LogObjectExecution ##PROCID;
DECLARE #UnsubscribeID INT = (SELECT TOP 1 UnsubscribeID
FROM Email.dbo.Unsubscribe
WHERE EmailAddress = #EmailAddress
ORDER BY UnsubscribeID DESC);
-- Unsubscribe
IF ((SELECT COUNT(*) FROM #UnsubscribeTypes) > 0)
BEGIN
IF(#UnsubscribeID IS NULL)
BEGIN
-- ADD UNSUBSCRIBE
INSERT INTO Email.dbo.Unsubscribe (EmailAddress, CreatedDate)
VALUES (#EmailAddress, CURRENT_TIMESTAMP)
SET #UnsubscribeID = ##IDENTITY;
END
-- Remove current mappings
DELETE FROM Email.dbo.UnsubscribeTypeMapping
WHERE UnsubscribeFK = #UnsubscribeID;
-- Add new mappings
INSERT INTO Email.dbo.UnsubscribeTypeMapping (UnsubscribeFK, UnsubscribeTypeFK, SentEmailFK)
SELECT
#UnsubscribeID, ID, #SentEmailID
FROM
#UnsubscribeTypes;
END
-- Subscribe
ELSE IF (#UnsubscribeID IS NOT NULL)
BEGIN
DELETE FROM Email.dbo.Unsubscribe
WHERE UnsubscribeID = #UnsubscribeID;
END
dbo.ListOfIDs is a table type. First, find out the type in your database, then check columns. generate a datatable with rows containing the UnsubscribeTypeFK ids.
The ADO.net code (not compiled)
Creating table
DataTable dt = new DataTable("Items");
dt.Columns.Add("ID", typeof(int));
dt.Rows.Add(4);
Calling proc
con = new SqlConnection(conStr);
con.Open();
using (con) {
// Configure the SqlCommand and SqlParameter.
SqlCommand sqlCmd = new SqlCommand("czone.SetAccountEmailPreference", con);
sqlCmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvpParam = sqlCmd.Parameters.AddWithValue("#UnsubscribeTypes", _dt); // TVP
tvpParam.SqlDbType = SqlDbType.Structured; //tells ADO.NET we are passing TVP
//pass other parameters
sqlCmd.ExecuteNonQuery();
}
con.Close();
You will find more about Table-Valued parameters here
I am executing a stored procedure in c# (through vs2008) using ado.net with an ExecuteScalar command. The stored proc returns the pkey of the new record entered, but ExecuteScalar is returning null. I look in the database and a record has indeed been added. I could use an output parameter to get the value, but then I won't know why this didn't work.
When I execute the sp in ssms, the pkey is returned.
What am I doing wrong?
Here is the C# code:
public int SaveNewPerson(EPerson ePerson)
{
int newPersonPkey;
SqlConnection cn = new SqlConnection(cnn.PersonData);
using (cn)
{
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "People.dbo.AddNewPerson";
cmd.Parameters.Add("#LastName", SqlDbType.VarChar, 150).Value = ePerson.LastName;
cmd.Parameters.Add("#FirstName", SqlDbType.VarChar, 150).Value = ePerson.FirstName;
cn.Open();
object result = cmd.ExecuteScalar();
newPersonPkey = int.Parse(result.ToString());
cn.Close();
}
catch (Exception e)
{
// call error method
throw new Exception(e.Message + " save new Person error ");
}
}
return newPersonPkey;
}
And this is the sp:
PROCEDURE [dbo].[AddNewPerson]
#FirstName varchar(50)
,#LastName varchar(50)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [People].[dbo].[Persons]
(
[FirstName]
,[LastName]
)
VALUES
(
#FirstName
,#LastName
)
declare #persons_PKey int
set #persons_PKey = ##IDENTITY
return #persons_PKey
end
The ExecuteScalar method returns the first field of the first record of the result, but as your query doesn't produce a result, it will return null.
You can either select the value instead of returning it from the stored procedure, or add a parameter with the direction set to ParameterDirection.ReturnValue to catch what the stored procedure returns.
Try changing the Stored Procedure to use a Select Statement to return the identity instead of using a return like this:
SELECT CAST(scope_identity() AS int)
Thus changing your procedure to:
PROCEDURE [dbo].[AddNewPerson]
#FirstName varchar(50)
,#LastName varchar(50)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [People].[dbo].[Persons]
(
[FirstName]
,[LastName]
)
VALUES
(
#FirstName
,#LastName
)
SELECT CAST(scope_identity() AS int)
end
From the documentation of the ExecuteScalar() on MSDN it says that it will return the first column of the first row in the result set or null otherwise if the result set is empty.