Returning values from database to WebMethod - c#

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

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

Retrieve results of a stored procedure on c#

I have a stored procedure that selects and returns a list of years. In sql server I call it like this:
DECLARE #return_value int
EXEC #return_value = [dbo].[TestName]
#del= 0
SELECT 'Return Value' = #return_value
In order to receive the list.
My SP looks like this:
USE [TestTable]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[TestName] (#delvarchar(7))
AS
BEGIN
SELECT YEAR( [added]) AS year FROM [MyTable]
GROUP BY YEAR( [added])
ORDER BY YEAR( [added]) DESC
END
I want to do the same from c# though and pass the values in a List.
What I am trying is:
using (var conn = new SqlConnection(constr))
using (var command = new SqlCommand("TestName", conn)
{
CommandType = CommandType.StoredProcedure
})
{
command.Parameters.AddWithValue("#del", del);
SqlParameter retval = command.Parameters.Add("#return_value", SqlDbType.VarChar);
retval.Direction = ParameterDirection.ReturnValue;
conn.Open();
command.ExecuteNonQuery();
int retunvalue = (int)command.Parameters["#return_value"].Value;
conn.Close();
return retunvalue;
}
This does not return any values though, instead it only returns 0. What am I doing wrong and how can I get the list inside a variable as specified?
Editing the code following John Hanna's advise I have something like this:
public List<string> getYears(string constr, int del)
{
using (var conn = new SqlConnection(constr))
using (var command = new SqlCommand("TestName", conn)
{
CommandType = CommandType.StoredProcedure
})
{
command.Parameters.AddWithValue("#del", del);
List<string> retunvalue = new List<string>();
conn.Open();
SqlDataReader reader;
reader = command.ExecuteReader();
conn.Close();
return retunvalue;
}
}
And by adding a breakpoint in order to explore reader I see that it is only contains errors:
Depth = '(reader).Depth' threw an exception of type 'System.InvalidOperationException'
As for Krishna's answer, dtList was empty with a count of 0, and I am not sure how to implement Badhon's suggestion.
ExecuteNonQuery() is so called because its for use with something that doesn't query the data. The 0 you get back is the number of rows the command changed.
Instead use ExecuteReader() and you will get back a SqlDataReader object that you can call Read() on to move through rows and then examine the details of each.
If you want to return that to another method use ExecuteReader(CommandBehavior.CloseConnection) and then rather than Close() or Dispose() the connection after you are finished, Close() or Dispose() the reader and that will close the connection then.
If you only have one row with one column (or for some reason only care about the first column of the first row even though there is more), then ExecuteScalar() is a convenient way to get just that single value.
You shouldn't use ExecuteNonQuery, rather use ExecuteDataSet as follow:
public List<DSM_DocPropIdentify> GetDocPropIdentify(string docPropIdentifyID, string action, out string errorNumber)
{
errorNumber = string.Empty;
List<DSM_DocPropIdentify> docPropIdentifyList = new List<DSM_DocPropIdentify>();
DatabaseProviderFactory factory = new DatabaseProviderFactory();
SqlDatabase db = factory.CreateDefault() as SqlDatabase;
using (DbCommand dbCommandWrapper = db.GetStoredProcCommand("GetDocPropIdentify"))
{
// Set parameters
db.AddInParameter(dbCommandWrapper, "#DocPropIdentifyID", SqlDbType.VarChar, docPropIdentifyID);
db.AddOutParameter(dbCommandWrapper, spStatusParam, DbType.String, 10);
// Execute SP.
DataSet ds = db.ExecuteDataSet(dbCommandWrapper);
if (!db.GetParameterValue(dbCommandWrapper, spStatusParam).IsNullOrZero())
{
// Get the error number, if error occurred.
errorNumber = db.GetParameterValue(dbCommandWrapper, spStatusParam).PrefixErrorCode();
}
else
{
if (ds.Tables[0].Rows.Count > 0)
{
DataTable dt1 = ds.Tables[0];
docPropIdentifyList = dt1.AsEnumerable().Select(reader => new DSM_DocPropIdentify
{
DocPropIdentifyID = reader.GetString("DocPropIdentifyID"),
DocPropertyID = reader.GetString("DocPropertyID"),
DocCategoryID = reader.GetString("DocCategoryID"),
DocTypeID = reader.GetString("DocTypeID"),
OwnerID = reader.GetString("OwnerID"),
IdentificationCode = reader.GetString("IdentificationCode"),
IdentificationSL = reader.GetString("IdentificationSL"),
AttributeGroup = reader.GetString("AttributeGroup"),
IdentificationAttribute = reader.GetString("IdentificationAttribute"),
IsRequired = reader.GetInt16("IsRequired"),
IsAuto = reader.GetInt16("IsAuto"),
SetOn = reader.GetString("SetOn"),
SetBy = reader.GetString("SetBy"),
ModifiedOn = reader.GetString("ModifiedOn"),
ModifiedBy = reader.GetString("ModifiedBy"),
Status = reader.GetInt32("Status"),
Remarks = reader.GetString("Remarks")
}).ToList();
}
}
}
return docPropIdentifyList;
}
Is dbo.TestName returns you a table or a value. If that returns you a table, then you would have to execute DataAdapter or execute DataReader. You should replace the above statement
as
DataTable dtList=new DataTable();
SqlDataAdapter adapter=new SqlDataAdapter();
adapter.SelectCommand=command;
adapter.Fill(dtList);
Then you can iterate through the datatable and add that to your list
List<Object> listObj=new List<Object>();
foreach(var rows in dtList.Rows)
{
listObj.Add(rows["Column_name"]);
}
I analysed your query, and found that, the statement
DECLARE #return_value int
EXEC #return_value = [dbo].[TestName]
#del= 0
SELECT 'Return Value' = #return_value
returns multiple tables. You can remove the last statement which is redundant.
SELECT 'Return Value' = #return_value
The datatable will now be populated with values.
Let me know if that works.

Cannot update record with SQL Server stored procedure

I've tried everything to get this to work and I know I'm missing something very simple.
I have a method that calls a stored procedure to update a record in a table.
It just so happens that one of the parameters is nullable in the database and the program value for it comes in as an empty string ("") for the vehicleNo column in this particular kind of situation.
All the other records get updated except if an empty string comes in and I try and update the record with the stored procedure.
Can someone please point out what I need to add to make the stored procedure or code work correctly?
Below the code, I've tried executing the stored procedure with hard coded values, but neither updates with the ImageID.
Stored procedure
ALTER PROCEDURE [dbo].[SPR_UPDATE_IMAGEID]
#ticketNo int,
#vehicleNo varchar(6) = NULL,
#imageID varchar(20)
AS
BEGIN
IF ((#vehicleNo = '') OR (#vehicleNo IS NULL))
BEGIN
UPDATE dbo.HH_FuelTkt
SET Image_ID = #imageID
WHERE Ticket_No = #ticketNo
AND Vehicle_No = NULL
END
ELSE
BEGIN
UPDATE dbo.HH_FuelTkt
SET Image_ID = #imageID
WHERE Ticket_No = #ticketNo
AND Vehicle_No = #vehicleNo
END END
C# code:
public static bool UpdateData(int ticketNo, string vehicleNo, string imageID)
{
int retValue = 0;
try
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["HHInboundSqlConnection"].ToString()))
{
SqlCommand cmd = new SqlCommand("SPR_UPDATE_IMAGEID", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ticketNo", ticketNo);
cmd.Parameters.AddWithValue("#vehicleNo", vehicleNo);
cmd.Parameters.AddWithValue("#imageID", imageID);
cmd.Connection.Open();
retValue = cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
throw e;
}
return (retValue > 0);
}
Manual stored procedure execution #1:
DECLARE #return_value int
EXEC #return_value = [dbo].[SPR_UPDATE_IMAGEID]
#ticketNo = 147058,
#vehicleNo = N'''''',
#imageID = N'39084'
SELECT 'Return Value' = #return_value
Manual stored procedure execution #2:
DECLARE #return_value int
EXEC #return_value = [dbo].[SPR_UPDATE_IMAGEID]
#ticketNo = 147058,
#vehicleNo = N'NULL',
#imageID = N'39084'
SELECT 'Return Value' = #return_value
IF ((#vehicleNo = '') OR (#vehicleNo IS NULL))
BEGIN
UPDATE dbo.HH_FuelTkt
SET Image_ID = #imageID
WHERE Ticket_No = #ticketNo
**AND Vehicle_No = NULL**
END
change the
AND Vehicle_No = NULL
to
AND Vehicle_No IS NULL
Normally on SQL check nullable value we use IS NULL instead of = NULL

Oracle Stored Procedure not returning any value

I'm calling an oracle stored procedure from a c# login form but it's not returning any value. Thus dt.rows.count below is always 0 and the if part of the if-else statement is never executed, it always gets to the else part.
C# code:
String sConnectionString = "Data Source=XE;User ID=system;Password=system;";
OracleConnection myConnection = new OracleConnection(sConnectionString);
myConnection.Open();
OracleCommand myCommand = new OracleCommand("spValidateDBA", myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandText = "spValidateDBA";
myCommand.Parameters.Add("UserName", OracleDbType.Varchar2, 50);
myCommand.Parameters["UserName"].Value = txtUsrId.Text.ToString();
myCommand.Parameters.Add("UserPassword", OracleDbType.Varchar2, 50);
myCommand.Parameters["UserPassword"].Value = txtPassword.Text.ToString();
myCommand.Parameters.Add("DataCount", OracleDbType.Int32, 20).Direction =
ParameterDirection.Output;
OracleDataReader myReader = myCommand.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(myReader);
if (dt.Rows.Count>0)
{
CustomMsgbox.Show("\tLogin Successful\t" + Environment.NewLine +
"Welcome to DB Utilities Tool", "DB Utilities Tool", "OK", "Cancel");
DBA dba = new DBA();
dba.Show();
this.Hide();
}
else
CustomMsgbox.Show("Please enter correct Username/password",
"DB Utilities Tool", "OK", "Cancel");
myConnection.Close();
}
Oracle stored procedure:
create or replace PROCEDURE spValidateDBA(
UserName IN VARCHAR2,
UserPassword IN VARCHAR2,
DataCount OUT INTEGER)
AS
BEGIN
select count(*) into DataCount from DBA_USER where USER_NAME=UserName and
USER_PWD=UserPassword and USER_ROLE = 'DBA';
END spValidateDBA;
Please note that table DBA_USER currently contains 1 row with values as:
USER_NAME USER_PWD USER_ROLE
dask password DBA
Thus, DataCount in the above stored procedure should return 1 row with value as 1 when the inputs from the login form are dask(username) & password(userpassword), however it's not returning anything.
Can someone please tell me where I'm going wrong with this? I really need to get this issue resolved very soon.
You are not returning any result set from your SP so your datatable will be always empty. You are returning value in the output parameter. Use ExecuteNonQuery and then read value from parameter.
Try this
myCommand.ExecuteNonQuery();
int dataCount = 0;
if(myCommand.Parameters["DataCount"] ! =null)
{
dataCount = Convert.ToInt32(myCommand.Parameters["DataCount"].Value);
}
if(dataCount > 0)
{
CustomMsgbox.Show("...");
}

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

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

Categories

Resources