SQL SUM negative value not being returned - asp.net

I have an SQL Query that looks like this -
CREATE PROCEDURE [dbo].[getMemberFundUnits]
-- Add the parameters for the stored procedure here
#member int,
#fundcode varchar(15),
#closingdate datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT (CASE WHEN SUM(units) IS Null THEN 0 ELSE SUM(units) END) As fundunits
FROM pe_minv
WHERE pmi_member = #member AND pmi_fund = #fundcode AND pmi_invested <= #closingdate
END
When I run the stored procedure like this -
DECLARE #return_value as float /*int*/
EXEC #return_value = [dbo].[getFundUnits]
#member = 9738,
#fundcode = N'58193',
#closingdate = N'07/21/2011'
SELECT 'Return Value' = #return_value
I get two results. The first is the correct one which is -0.0060 and the second #return_value which is 0
This is also the case when I call the stored procedure from my code, I get a 0 back instead of the -0.0060 that I want.
This is how I am calling the stored procedure from my code:
Dim ds As New DataSet()
Dim cmd As New SqlCommand("getMemberFundUnits", conn)
cmd.CommandType = CommandType.StoredProcedure
Dim p_pm_member As New SqlParameter("#member", SqlDbType.Int)
p_pm_member.Value = pm_member
cmd.Parameters.Add(p_pm_member)
Dim p_fund_code As New SqlParameter("#fundcode", SqlDbType.VarChar)
p_fund_code.Value = fund_code
cmd.Parameters.Add(p_fund_code)
Dim p_period_closing_date As New SqlParameter("#closingdate", SqlDbType.DateTime)
p_period_closing_date.Value = period_closing_date
cmd.Parameters.Add(p_period_closing_date)
Dim da As New SqlDataAdapter(cmd)
da.Fill(ds)
Does anyone have any ideas why this might be happening?
Thanks!

DECLARE #return_value as int
Your variable is defined as int. Int can't hold decimal values, so the return value is rounded. Try to declare your var as float.
List of SQL Server data types

The RETURN is always int so it is truncated inside the stored procedure.
As per MSDN
RETURN [ integer_expression ]
You need to use an OUTPUT parameter that is float:
CREATE PROC [dbo].[getFundUnits]
#member...,
#fundcode...',
#closingdate...,
#SummedValue float OUTPUT
AS
...
SELECT #SummedValue = (CASE WHEN SUM(nits) IS Null THEN 0 ELSE SUM(units) END) As fundunits
...
GO
And you call it as
DECLARE #return_value as float
EXEC [dbo].[getFundUnits]
#member = 9738,
#fundcode = N'58193',
#closingdate = N'07/21/2011',
#return_value OUTPUT
SELECT 'Return Value' = #return_value
RETURN is used (if at all) only for execution status usually: meaningful data is via output parameters or a resultset. I no longer use RETURN...

Try declaring the return value as Decimal with precision.
DECLARE #return_value as decimal(18,4)
Also, why are you filling a dataset for only returning one column. Use a sqldatareader and retrieve the values as decimal. Dataset is very resource intensive.

Related

Stored Procedure not working from ASP.NET

I have the following stored procedure:
alter proc SPCP_ProgramUpdate
#ID int,
#UserID int,
#Name nvarchar(150),
#University int,
#Level tinyint,
#isActive bit
as
update tblUniversityProgram set University_Fkey = #University, Level_Fkey = #Level, Program_Name = #Name, EditDate = GETDATE(), EditUser = #UserID, isActive = #isActive
where tblUniversityProgram.ID = #ID
When I run the stored procedure from SSMS, it works as intended.
However, when I run that stored procedure from ASP.NET using this code:
Dim varDbconn As New SqlConnection
Dim varDbcomm As SqlCommand
Dim varDbRead As SqlDataReader
varDbconn.ConnectionString = ConfigurationManager.ConnectionStrings("CPDB_ConnectionString").ToString
varDbconn.Open()
If Request.QueryString("program") <> "" Then
varDbcomm = New SqlCommand("SPCP_ProgramUpdate", varDbconn)
varDbcomm.CommandType = CommandType.StoredProcedure
varDbcomm.Parameters.AddWithValue("#ID", Request.QueryString("program")).DbType = DbType.Int32
varDbcomm.Parameters.AddWithValue("#UserID", Session("UserID")).DbType = DbType.Int32
varDbcomm.Parameters.AddWithValue("#University", Session("DecryptID")).DbType = DbType.Int32
varDbcomm.Parameters.AddWithValue("#Level", ddlLevel.SelectedValue).DbType = DbType.Byte
varDbcomm.Parameters.AddWithValue("#isActive", chkisActive.Checked).DbType = DbType.Boolean
varDbcomm.Parameters.AddWithValue("#Name", txttitle.Text).DbType = DbType.String
varDbcomm.ExecuteNonQuery()
varDbcomm.Dispose()
Else
....
End IF
varDbconn.Close()
nothing happens.
Any ideas?
The most likely answer to your question is that the value you are getting out of the querystring for program is not the Id in your database that you expect.
At the minute, your code is reading in input values and passing them to a stored procedure without any validation of your expected values - missing session for example could cause you all sorts of unexpected issues.
Debug your code and see exactly what parameters you are passing to your DB. Check your connection string to see that you are hitting the database where you have amended your stored procedure.
What you have should work. I would use parmaters.Add in place of addwith, but that should not really matter.
Try adding this code right after you are done setting up the parmaters:
Debug.Print("SQL = " & varDbcomm.CommandText)
For Each p As SqlParameter In varDbcomm.Parameters
Debug.Print(p.ParameterName & "->" & p.Value)
Next
That way in the debug window (or immediate depending on VS settings), you see a list of param values, and the parameter names. I suspect one of the session() values is messed up here.

How to store more than 8000 characters and assign large concatenated string in SQL Server 2008?

I am trying to concatenate the large number of id'd and to update the status of all id's.
For example:
aclid in (4604019,4604018,4604017,4604016,4604015,4604014,4604013,4604012,4604011,4604010,4604009,4604008,4604007,4604006,4604005,4604004,4604003,4604002,4604001,4604000,4603999,4603998,4603997,4603996,4603995,4603994,4603993,4603992,4603991,4603990,4603989,4603988)`
Please check my stored procedure:
ALTER PROCEDURE [dbo].[VT_ACLReportChangeStatus]
(#ChangeStatus nvarchar(50) = null,
#ACLId nvarchar(max))
AS
/* Exec VT_ACLReportChangeStatus 'Complete','4599473,4599472,4599471,4599469,4599468' */
BEGIN
UPDATE VT_ACLReport
SET Status = #ChangeStatus
WHERE ACLId IN (SELECT * FROM SplitDelimiterString(#ACLId,','))
END
Please check my code behind:
ACLId = ACLId.ToString().Trim(',');
using (SqlConnection con = new SqlConnection(cs))
{
cmd = new SqlCommand("VT_ACLReportChangeStatus", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandTimeout = 3600;
cmd.Parameters.Add(new SqlParameter("#ACLId", SqlDbType.NVarChar,-1));
cmd.Parameters.Add(new SqlParameter("#ChangeStatus", SqlDbType.NVarChar, 50));
cmd.Parameters["#ACLId"].Value = ACLId;
cmd.Parameters["#ChangeStatus"].Value = ddlChangeStatus.SelectedItem.Text.ToString();
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
AclId column data type is bigint identity.
Please can you help me in concatenating large string and to update all rows whose aclid is present.
I would suggest, create one user defined table type in sql and one class in sourecode with your respective data. You can pass object of this class to sql and in your SP you can use join between main table and this table(which is received as input parameter) to update data.
Thanks all of you for your answers.. Actually it was silly mistake,while calling splitting function in Stored procedure. In function it was varchar(8000). :) solved it.
ALTER FUNCTION [dbo].[SplitDelimiterString] (#StringWithDelimiter VARCHAR(max), #Delimiter VARCHAR(max))
RETURNS #ItemTable TABLE (Item VARCHAR(max))
AS
BEGIN
DECLARE #StartingPosition INT;
DECLARE #ItemInString VARCHAR(max);
SELECT #StartingPosition = 1;
--Return if string is null or empty
IF LEN(#StringWithDelimiter) = 0 OR #StringWithDelimiter IS NULL RETURN;
WHILE #StartingPosition > 0
BEGIN
--Get starting index of delimiter .. If string
--doesn't contain any delimiter than it will returl 0
SET #StartingPosition = CHARINDEX(#Delimiter,#StringWithDelimiter);
--Get item from string
IF #StartingPosition > 0
SET #ItemInString = SUBSTRING(#StringWithDelimiter,0,#StartingPosition)
ELSE
SET #ItemInString = #StringWithDelimiter;
--If item isn't empty than add to return table
IF( LEN(#ItemInString) > 0)
INSERT INTO #ItemTable(Item) VALUES (#ItemInString);
--Remove inserted item from string
SET #StringWithDelimiter = SUBSTRING(#StringWithDelimiter,#StartingPosition +
LEN(#Delimiter),LEN(#StringWithDelimiter) - #StartingPosition)
--Break loop if string is empty
IF LEN(#StringWithDelimiter) = 0 BREAK;
END
RETURN
END

return output parameter in sql server

Here condition is true then it return true otherwise return false
ALTER PROCEDURE spAppliedJobOrnot
--Here job is already applied then it return true otherwise return false
#check bit OUTPUT,
#UserId numeric,
#JobId numeric
AS
BEGIN
SET NOCOUNT ON;
if exists (SELECT 1 FROM StudentInbox_Activities WHERE JobId=#JobId and StudentId=#UserId and
JobAppliedDate is not null)
BEGIN
SET #check=1 --The job is applied so check=true
END
ELSE
BEGIN
SET #check=0;
END
END
GO
Here how to get the #check value
When using OUTPUT params, you need to return the value in the calling statement.
Have a lok at this example
SQL Fiddle DEMO
Procedure to do whatever
CREATE PROCEDURE FOO(#BAR INT OUTPUT)
AS
BEGIN
SET #BAR = -1
END;
And then calling statement
DECLARE #TADA INT = 0
EXEC FOO #TADA OUTPUT
SELECT #TADA
Since you have #check as output parameter, you can get this value from your application too.
If it is in C#, you can use something like the following,
SqlCommand cmd = new SqlCommand("SP_NAME");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#param1", param1);
cmd.Parameters.AddWithValue("#param2", param2);
cmd.Parameters.Add("#check", SqlDbType.Int);
cmd.Parameters["#check"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery()
return Convert.ToInt32(cmd.Parameters["#check"].Value);
Add the following code after your if- end statement, before procedure end statement
select #check
Then run the procedure.
Maybe this link might be helpful for your problem about ASP.Net.

Stored Procedure Returns zero results

I developed a search page containing a textbox control for entering a number and button to display the respective results in a Gridview. The page functions off a stored procedure. The sql query returns the expected results when ran via SQL Server Manager when I manually type in the number, but when used in my stored procedure, I get zero results.
This is the code behind the button-event handler:
Dim ds As New DataSet()
Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings("ShipperNotificationConnectionString1").ToString())
Using command As New SqlCommand()
command.CommandType = CommandType.StoredProcedure
command.CommandText = "getPON"
command.Connection = connection
command.Parameters.AddWithValue("#PON", txtPON.Text)
connection.Open()
Dim a As New SqlDataAdapter(command)
a.Fill(ds)
End Using
End Using
gvPON.DataSource = ds
gvPON.DataBind()
...The following is the stored procedure:
ALTER PROCEDURE [dbo].[getPON]
(
#PON varchar
)
AS
BEGIN
SELECT SupplierCompany.company_name, SupplierCompany.Address1, SupplierCompany.Address2, SupplierCompany.City, SupplierCompany.State,
SupplierCompany.Zip, Shipment_Po.PONumber, Shipment.TotalWeight, Shipment.NoOfPallets, Shipment.PalletIdentical
FROM SupplierCompany INNER JOIN
Shipment ON SupplierCompany.Company_guid = Shipment.Company_Guid INNER JOIN
Shipment_Po ON Shipment.Shipment_Guid = Shipment_Po.Shipment_guid
WHERE Shipment_Po.PONumber = '''+ #PON +'''
END
...Could someone please provide some direction?
The problem is the stored procedure. The expression:
WHERE Shipment_Po.PONumber = '''+ #PON +'''
Is not doing what you think. It is doing the following comparison:
WHERE Shipment_Po.PONumber = '+#PON+'
Or something like that. In other words, you are mixing dynamic SQL expressions with regular SQL. Try doing:
WHERE Shipment_Po.PONumber = #PON
If you are concerned about the cast to the right type:
WHERE Shipment_Po.PONumber = (case when isnumeric(#PON) = 1 then cast(#PON as int) end)

Executenonquery return value

I want to perform a search on a table to see if record exists. I do not want to perform insert or update after. I have done this already but somehow I cannot get this to work. On my asp.net page I cannot seem to get any value returned. The error is "input string not in correct format" I ma sure it is obvious but I cannot seem to see it now!
here is my code:
Dim con As New SqlConnection("connstring")
Dim cmd As New SqlCommand("checkname", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New SqlParameter("#d", SqlDbType.Int))
cmd.Parameters("#id").Value = TextBox1.Text
Dim para As New SqlParameter
para.Direction = ParameterDirection.ReturnValue
para.ParameterName = "returnvalue"
cmd.Parameters.Add(para)
con.Open()
cmd.ExecuteNonQuery()
Dim exists As Integer
exists = Convert.ToInt32(cmd.Parameters("returnvalue").Value)
If exists = 1 Then
Label1.Text = "You......"
ElseIf exists = 0 Then
Label1.Text = "You....."
End If
con.Close()
stored procedure:
CREATE PROCEDURE checkname
-- Add the parameters for the stored procedure here
#id int
AS
--This means it exists, return it to ASP and tell us
-- SELECT 'already exists'
IF EXISTS(SELECT * FROM attendees WHERE id = #id)
BEGIN
RETURN 1
END
ELSE
BEGIN
RETURN 0
END
You need to ensure that you are passing an integer.
int intValue;
if(!int.TryParse(TextBox1.Text, out intValue))
{
// Update your page to indicate an error
return;
}
cmd.Parameters.Add(New SqlParameter("id", SqlDbType.Int));
cmd.Parameters("id").Value = intValue;
(Technically you don't need the "#" character when
defining the parameters in the .NET
code.)
You have declared your procedure parameter as #d instead of #id. Also a return parameter cannot be an input parameter. The return value should be an exit code. You most likely want to create an output parameter and set that to 1 or zero inside of your stored procedure.
Edit: to clarify, the return value is generally regarded as an indicator of correct execution. Zero usually means success, where any other numeric value is generally regarded as an error code. That is why I recommended adding an output parameter instead of adding a return value parameter.
ExecuteNonQuery returns the number of rows affected. Therefore the return values that you set in your stored procedure are thrown away and will not be returned by the ExecuteNonQuery method.
ExecuteNonQuery is used to Insert / Delete / Update operations. Not for SELECT, you need either ExecuteScalar or ExecuteReader methods. This link will help you to know how to use output parameters : http://aspdotnet-suresh.blogspot.com/2010/10/introduction-here-i-will-explain-how-to.html

Resources