SQL/C# Get ID of the row affected by Insert - c#

I'm trying to get the ID of the row affected in "real time". I could check it for the parameters used or the last row, but I want to do it with the least delay possible, so that there isn't multiple users mixing information in the tables.
Tried so far:
public int setFileInfo(string fileName, int filePrivacy, string filePassword, string fileDesc, string fileOwner)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["bitRain"].ConnectionString))
{
SqlCommand cmd = new SqlCommand("dbo.Upload", conn);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
if(!String.IsNullOrEmpty(filePassword))
{
filePassword = FormsAuthentication.HashPasswordForStoringInConfigFile(filePassword, "MD5");
}
try
{
conn.Open();
cmd.Parameters.Add("#fileName", fileName);
cmd.Parameters.Add("#filePrivacy", filePrivacy);
cmd.Parameters.Add("#filePassword", filePassword);
cmd.Parameters.Add("#fileDescription", fileDesc);
cmd.Parameters.Add("#fileOwner", fileOwner);
int fileID = (int)cmd.ExecuteScalar();
return fileID;
}
catch (Exception ex)
{ }
finally
{
conn.Close();
}
return -1;
}
}
Stored Procedure:
CREATE PROCEDURE [dbo].[Upload]
#fileName nvarchar(20),
#filePrivacy int,
#filePassword nvarchar(50),
#fileDescription nvarchar(200),
#fileOwner nvarchar(14)
AS
INSERT INTO Files ([FileName], FilePrivacy, FilePassword, FileDescription, FileOwner)
VALUES (#fileName, #filePrivacy, #filePassword, #fileDescription, #fileOwner)
RETURN 0
I need some OUTPUT parameter, but I don't know how to use it and msdn examples aren't clear enough for me.

Stored Procedure:
CREATE PROCEDURE [dbo].[Upload]
#fileName nvarchar(20),
#filePrivacy int,
#filePassword nvarchar(50),
#fileDescription nvarchar(200),
#fileOwner nvarchar(14),
#id int out
AS
INSERT INTO Files ([FileName], FilePrivacy, FilePassword, FileDescription, FileOwner)
VALUES (#fileName, #filePrivacy, #filePassword, #fileDescription, #fileOwner)
set #id = SCOPE_IDENTITY()
END
In cs add
cmd.Parameters["#id"].Direction = ParameterDirection.Output;

try to use SCOPE_IDENTITY function

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

Returning values from database to WebMethod

I need to enter some value in the textbox end save it to the database.
But if there is a duplicate value then the value must not be saved.
Basically, string lvl is successfully passed to the WebMethod from front-end via ajax.
Procedure getDuplicate is a simple select that checks if there is a value of lvl is already stored in the database. And InsertObject procedure inserts the value in the database.
If the value(lvl) exists then the ID of that value is return and stored in the Count integer.
The problem is if Count is returned with id number then if statement works,
and if there is no value in the database Count just does not receive any values and the procedure fails and goes straight to the catch part of the code.
I think there's a problem with the returning type from a database when there is no value in it. It is not INT or something.
Can anyone help, please?
[WebMethod(EnableSession = true)]
public static void GetCollection(string lvl)
{
string conn = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
using (SqlConnection connection = new SqlConnection(conn))
try
{
connection.Open();
SqlCommand cmdCount = new SqlCommand("getDuplicate", connection);
cmdCount.CommandType = CommandType.StoredProcedure;
cmdCount.Parameters.AddWithValue("#ObjekatName", lvl);
int count = (int)cmdCount.ExecuteScalar();
if (count > 0)
{
}
else
{
SqlCommand cmdProc = new SqlCommand("InsertObjekat", connection);
cmdProc.CommandType = CommandType.StoredProcedure;
cmdProc.Parameters.AddWithValue("#ObjekatName", lvl);
cmdProc.ExecuteNonQuery();
//strMsg = "Saved successfully.";
}
}
catch
{
}
finally
{
connection.Close();
}
return;
getDuplicate procedure
ALTER PROCEDURE [dbo].[GetDuplicate]
#ObjekatName nvarchar(20)
AS
BEGIN
SET NOCOUNT ON
SELECT TOP 1000 [ObjekatID]
,[ObjekatName]
FROM [MyApp].[dbo].[Objekat]
WHERE ObjekatName = #ObjekatName
END
Please change your GetDuplicate proc as below. It will always return a value.
CREATE PROCEDURE [dbo].[GetDuplicate]
#name nvarchar(20)
AS
BEGIN
DECLARE #duplicateCount int
SELECT #duplicateCount=count(*) FROM [dbo].[employee] WHERE name = #name
RETURN #duplicateCount
END

How can I get the Last Index of mysql that has been inserted to C# code behind?

So I have a MySql stored procedure for inserting a row:
DELIMITER $$
CREATE PROCEDURE AddPosition(
IN strName VARCHAR(1000)
,IN strPositionType VARCHAR(1000)
,OUT intPositionId INT
)
BEGIN
INSERT INTO positions (
positionName
, positionType
)
VALUES(
strName
,strPositionType
);
SET intPositionId = LAST_INSERT_ID();
END
Honestly, I'm not really sure if this SET intPositionId = LAST_INSERT_ID(); works, I want to get the value of IntPositionId and bring it to C#
in my c#;
public bool AddItem(Position data)
{
int newId = 0;
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "AddPosition";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("strName", data.PositionName).Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("strPositionType", data.PositionType).Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("intPositionId", SqlDbType.Int).Direction = ParameterDirection.Output;
try
{
MyHelper.MyExecuteNonQuery(cmd);
newId = (int) cmd.Parameters["intPositionId"].Value;
return true;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return false;
}
}
The newId = (int) cmd.Parameters["intPositionId"].Value; says "Specified cast is not valid."
when I tried to use debugging to find out what cmd.Parameters["intPositionId"].Value; returns,
it is just plain object with no value. I guess the SET intPositionId = LAST_INSERT_ID(); didnt work.
so where did I go wrong here?

Cannot find stored procedure

I have many stored procedure calls in my C# code, but only this one keeps failing. I'm running VS 2012 and SQL Server 2008 R2. My connection string is the same for all my stored procedures and I have the same permissions on all of them.
I get this error
Could not find stored procedure 'StP_Map_Preload #bldg, #linePos, #startD, #lineNo, #Pgrm, #apPos, #sessionID'.
System.Exception {System.Data.SqlClient.SqlException}
on this line:
SqlDataReader dr = cmd.ExecuteReader();:
I have tried creating a new stored procedure with the same code, setting permissions, but it fails too.
public ArrayList DetailPreload(string bldg, string linePos, DateTime startD, string lineNo, string Pgrm, int apPos, string sessionID)
{
string strSQL = "StP_Map_Preload #bldg, #linePos, #startD, #lineNo, #Pgrm, #apPos, #sessionID";
ArrayList list = new ArrayList();
using (SqlConnection conStr = new SqlConnection(connM))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#bldg", bldg);
cmd.Parameters.AddWithValue("#linePos", linePos);
cmd.Parameters.AddWithValue("#startD", startD);
cmd.Parameters.AddWithValue("#lineNo", lineNo);
cmd.Parameters.AddWithValue("#Pgrm", Pgrm);
cmd.Parameters.AddWithValue("#apPos", apPos);
cmd.Parameters.AddWithValue("#sessionID", sessionID);
cmd.CommandText = strSQL;
cmd.Connection = conStr;
conStr.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
list.Add(new
{
company = dr["Company"],
Pgrm = dr["Pgrm"],
lineNum = dr["lineNum"],
lineStation = dr["lineStation"],
jobCount = dr["Job"],
item = dr["Item"],
qty = dr["Qty"],
partQty = dr["partQty"],
invCnt = dr["invCnt"],
runID = dr["runID"]
});
}
conStr.Close();
return list;
}
}
}
My stored procedure is in SQL Server and I can execute it in SQL Server
/*
StP_Map_Preload 'AA-12', '7', '09/19/2014', '', '247', 7, 'val2gxfh5ihoqy4tshzl4tp3'
*/
ALTER proc [dbo].[StP_Map_Preload]
#Bldg varchar(10),
#linePos varchar(5),
#startD date,
#LineNo varchar(5),
#Pgrm varchar(5),
#apPos int,
#sessionID varchar(50)
AS
BEGIN
declare #sql varchar(Max), #PST varchar(20),
#SI1 varchar(5), #SI2 varchar(5), #SI3 varchar(5),
#hasAP bit, #CCLen varchar,
#Co varchar(5), #CCs varchar(25), #lsGrp varchar(max)...
Change your line to
string strSQL = "StP_Map_Preload";
There is no need to list the parameters in the string that names the stored procedure.

Data Access Layer

I have created DataAccessLayer.cs file which helps me to make connection withe the database for insert records into the database and i have created store procedure.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
public class DataAccessLayer
{
SqlConnection con = new SqlConnection("Connection String");
SqlCommand cmd;
public DataAccessLayer()
{
//
// TODO: Add constructor logic here
//
}
public int ExecuteProcedure(String procname, SqlParameter[]param)
{
cmd = new SqlCommand();
cmd.CommandText = procname;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
foreach (SqlParameter obj in param)
{
cmd.Parameters.Add(obj);
}
con.Open();
int i = cmd.ExecuteNonQuery();
con.Close();
return i;
}
}
Code for inserting record into data base using store procedure
SqlParameter[] param = new SqlParameter[]
{
new SqlParameter("#Name",txtFirstName.Text),
new SqlParameter("#DOB",txtDOB.Text),
new SqlParameter("#Address",txtAddress.Text),
new SqlParameter("#CN",ddlCountry.SelectedValue),
new SqlParameter("#SN",ddlState.SelectedValue),
new SqlParameter("CNN",ddlCity.SelectedValue),
new SqlParameter("#Mobile",txtMobile.Text),
new SqlParameter("#Email",txtEmail.Text),
new SqlParameter("#Pincode",txtPincode.Text),
new SqlParameter("#returnval",SqlDbType.Int)
};
int i = DAL.ExecuteProcedure("AddContactInfo", param);
if (i == 1)
{
lblError.Text = "Sucess";
}
else
{
lblError.Text = "Not Sucess";
}
Store Procedure for inserting records
ALTER proc [dbo].[AddContactInfo]
(
#Name varchar(50),
#DOB datetime,
#Address Varchar(max),
#Mobile varchar(15),
#Email varchar(50),
#CN int,
#SN int,
#CNN int,
#Pincode int,
#returnval int output
)
As
Begin
if exists(select Id from Contact_Info where Email=#Email)
begin
set #returnval=-2;
return #returnval;
end
else
begin
insert into Contact_Info(Name,DOB,Address,CountryName,StateName,CityName,Pincode,Mobile,Email,CreatedOn )
values(#Name,#DOB,#Address,#CN,#SN,#CNN,#Pincode,#Mobile,#Email,GETDATE())
if ##ERROR<>0
begin
set #returnval=-3;
return #returnval;
end
else
begin
set #returnval=1;
return #returnval;
end
end
End
But i am getting error which is "Procedure or function 'AddContactInfo' expects parameter '#returnval', which was not supplied."
You'll have to set your new SqlParameter("#returnval", SqlDbType.Int) to be an output parameter:
foreach (SqlParameter obj in param)
{
if (cmd.ParameterName == "#returnval")
{
cmd.Direction = ParameterDirection.Output
}
cmd.Parameters.Add(obj);
}
Of course, this expects all SP's to have the same #returnval when appropriate. It's better to set it when creating the list of parameters.

Categories

Resources