Cannot update record with SQL Server stored procedure - c#

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

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

stored procedure expect some input though its provided

I am stuck in a problem. i am getting error "Procedure or function 'SP_RPT_User' expects parameter '#deptName', which was not supplied." in c# application while parameter is provided. even i copied and replaced the name. still no success.
public DataTable SP_RPT_User(int loggedid, String deptName, String OfficeName, String empType)
{
int updatedrows = 0;
DataTable table = new DataTable();
try
{
cCommand = new System.Data.SqlClient.SqlCommand("SP_RPT_User", connection);
cCommand.CommandType = CommandType.StoredProcedure;
cCommand.Parameters.Add("#loggedId", SqlDbType.Int).Value = loggedid;
cCommand.Parameters.Add("#deptName", SqlDbType.NVarChar, 200).Value = deptName;
cCommand.Parameters.Add("#OfficeName", SqlDbType.VarChar, 150).Value = OfficeName;
cCommand.Parameters.Add("#empType", SqlDbType.VarChar, 150).Value = empType;
cCommand.CommandTimeout = 90000;
connection.Open();
updatedrows = cCommand.ExecuteNonQuery();
using (var da = new SqlDataAdapter(cCommand))
{
cCommand.CommandType = CommandType.StoredProcedure;
da.Fill(table);
}
}
catch (Exception Ex)
{
connection.Close();
// return -100;
}
finally
{
connection.Close();
}
return table;
}
Stored Procedure
ALTER PROCEDURE [dbo].[SP_RPT_User]
-- Add the parameters for the stored procedure here
#loggedId int,
#deptName NVarChar(200),
#OfficeName varchar(150),
#empType varchar(150)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #sql nvarchar(max);
set #sql ='SELECT ...'; // here is one query
if(#deptName != '')
set #sql = #sql + ' and dbo.TB_Department.name like ''%'+#deptName+'%''';
Declare #params nvarchar(500)
SELECT #params ='#loggedId int,'+
'#deptName NVarChar(200),'+
'#OfficeName varchar(150),'+
'#empType varchar(150)'
exec sp_executesql #sql, #params,#loggedId,#deptName,#OfficeName,#empType;
END
Can anyone help. thanks in advance.
i am using sql server 2014 and vs2015.
The educated guess I have is that deptName value in C# is null while you execute the query. In such case you should pass DBNull.Value to have null as parameter value:
var param = cCommand.Parameters.Add("#deptName", SqlDbType.NVarChar, 200);
param.Value = deptName ?? DBNull.Value;
From your procedure I see that you compare with empty string so use ?? string.Empty to satisfy that condition.

load Output parameters from SQL stored procedure c#

I am trying to load output parameters from my SQL stored procedure.
USE [EdiMon_Beta]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetClients]
-- Add the parameters for the stored procedure here
#sender nvarchar(max),
#subSender nvarchar(max),
#receiver nvarchar(max),
#subReceiver nvarchar(max),
#msgTypeID int,
#ErrorMsg nvarchar(max) = null OUTPUT,
#processId int = 0 OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE
#senderId int,
#subSenderId int,
#receiverId int,
#subReceiverId int
SELECT
#senderId = ID
FROM [dbo].[Party_Client]
WHERE
[Number] LIKE #sender
IF(#senderId IS NULL)
BEGIN
SET #ErrorMsg = 'Sender does not exist'
RETURN ;
END
SELECT
#subSenderId = ID
FROM [dbo].[Party_Client]
WHERE
[Number] LIKE #subSender
AND ParentId = #senderId
AND IsSubClient = 1
IF(#subSenderId IS NULL)
BEGIN
SET #ErrorMsg = 'SubSender does not exist'
RETURN ;
END
SELECT
#receiver = ID
FROM [dbo].[Party_Client]
WHERE
[Number] LIKE #receiver
IF(#receiverId IS NULL)
BEGIN
SET #ErrorMsg = 'Receiver does not exist'
RETURN;
END
SELECT
#subReceiverId = ID
FROM [dbo].[Party_Client]
WHERE
[Number] LIKE #subReceiver
AND ParentId = #receiverId
AND IsSubClient = 1
IF(#subReceiverId IS NULL)
BEGIN
SET #ErrorMsg = 'SubReceiver does not exist'
RETURN ;
END
SELECT #processId = ID FROM [dbo].[Party_Processes]
WHERE MsgTypeId = #msgTypeID
AND SenderId = #senderId
AND ReceiverId = #receiverId
END
And reading it with c# code:
using (SqlConnection connection = new SqlConnection(connectionString))
{
try
{
SqlCommand command = new SqlCommand("GetClients", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#sender", sender));
command.Parameters.Add(new SqlParameter("#subSender", subSender));
command.Parameters.Add(new SqlParameter("#receiver", receiver));
command.Parameters.Add(new SqlParameter("#subReceiver", subReceiver));
command.Parameters.Add(new SqlParameter("#msgTypeID", msgTypeID));
var errorMsgParam = command.Parameters.Add(new SqlParameter("#ErrorMsg", SqlDbType.NVarChar, -1));
errorMsgParam.Direction = ParameterDirection.Output;
var processIdParam = command.Parameters.Add(new SqlParameter("#processId", SqlDbType.Int, -1));
processIdParam.Direction = ParameterDirection.Output;
connection.Open();
command.ExecuteNonQuery();
var processIDResult = command.Parameters["#processId"].Value;
var errorMsgResult = command.Parameters["#ErrorMsg"].Value;
processID = (int)processIDResult;
errorMsg = errorMsgResult.ToString();
}
}
The thing is, I always get null as result. This is Helper class for xsl mapping in biztalk. All the input parameters are directly from the map. I want to check our database, if these clients exist and also, if process which using them exist.
thanks for your help :)
OK, i solved this. Problem was in 2 or 3 places. For first i had mistake in my SQL stored procedure which is not universal so i didnt post it here (it applies only to my project). The other mistake was in converting my output from stored procedure:
processID = command.Parameters["#processId"].Value as int?;
errorMsg = command.Parameters["#ErrorMsg"].Value == DBNull.Value ? string.Empty : command.Parameters["#ErrorMsg"].Value.ToString();
where processID is declared as "int?" and errorMsg is declared as "string".
Thanks for all the help.

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)

Can't update foreign key by passing parameter to stored procedure

I have an application which changes fields in a table. It's a simple form where the user can change the company associated with a group.
.NET
public static string EditGroup(vw_Group_Model editGroup)
{
string outcome = "";
if (editGroup.RowType == "ALF")
{
try
{
using (SqlConnection conn = AlfOnlineConnection())
{
conn.Open();
UserManager.Models.vw_Group_Model model = new vw_Group_Model();
using (var command = new SqlCommand("sp_UserManager_EditGroup", conn))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#CompanyId", SqlDbType.Int).SqlValue = editGroup.companyId;
command.Parameters.Add("#GroupId", SqlDbType.Int).SqlValue = editGroup.groupId;
//command.Parameters.Add("#CompanyName", SqlDbType.NVarChar).SqlValue = editGroup.selected_company;
//command.Parameters.Add("#GroupName", SqlDbType.NVarChar).SqlValue = editGroup.groupName;
command.Parameters.Add("#StartDate", SqlDbType.DateTime).SqlValue = editGroup.StartDate;
command.Parameters.Add("#EndDate", SqlDbType.DateTime).SqlValue = editGroup.EndDate;
switch (editGroup.IsActive)
{
case true:
command.Parameters.Add("#isactive", SqlDbType.TinyInt).SqlValue = 1;
break;
case false:
command.Parameters.Add("#isactive", SqlDbType.TinyInt).SqlValue = 0;
break;
}
int rowsEdited = command.ExecuteNonQuery();
if (rowsEdited == 1)
{
outcome = "Row successfully edited.";
}
}
}
}
catch (SqlException ex)
{
return ex.ToString();
}
}
T-SQL
USE [BradOnline]
GO
/****** Object: StoredProcedure [dbo].[sp_UserManager_EditGroup] Script Date: 01/17/2013 13:11:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[sp_UserManager_EditGroup]
#GroupId INT,
#CompanyId INT,
--#GroupName NVARCHAR(50),
--#CompanyName NVARCHAR(50),
#StartDate DATETIME,
#EndDate DATETIME,
#isactive TINYINT
AS
BEGIN
DECLARE #AccountManagerId uniqueidentifier
SET #AccountManagerId = '7A1DC75D-2628-4F8D-A376-9382A0762568'
--(SELECT G.AccountManagerId FROM dbo.aspnet_Custom_Groups AS G
-- WHERE Id = #GroupId)
--DECLARE #CompanyId BIGINT
--SET #CompanyId = (SELECT MAX(c.Id) FROM dbo.aspnet_Custom_Companies AS c
-- WHERE c.Name = #CompanyName)
UPDATE
[dbo].[aspnet_Custom_Groups]
SET
--[Name] = #GroupName,
[StartDate] = #StartDate,
[EndDate] = #EndDate,
[IsActive] = #isactive,
[AccountManagerId] = NULL,
[CompanyId] = #CompanyId
WHERE
[Id] = #GroupId
END
In the SQL if I hard-code the values for the update it works, but if i pass the values in it doesn't. I have been looking at it for ages but haven't gotten anywhere. The parameters in my application contain values when I check with a breakpoint
Instead of setting your parameter values through SqlParameter.SqlValue, try using SqlParameter.Value like below.
command.Parameters.Add("#CompanyId", SqlDbType.Int).Value = editGroup.companyId;

Categories

Resources