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)
Related
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.
Its a ASP.net application in VS2008, connecting to SQL 2005 database.
No errors calling the Stored procedure, db update is successful but the OUTPUT param returns DBnull all the time. Below the vb code:
Dim ConnectString As String = "", connect As New Data.SqlClient.SqlConnection
ConnectString = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
connect.ConnectionString = ConnectString
Dim cmd As New SqlCommand("saveAccess", connect)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New SqlParameter("#Name", "SampleName"))
Dim outparam As SqlParameter = New SqlParameter("#returnValue", SqlDbType.Int)
outparam.Direction = ParameterDirection.Output
cmd.Parameters.Add(outparam)
connect.Open()
cmd.ExecuteNonQuery()
If IsDBNull(cmd.Parameters("#returnValue").Value Then
Response.Write("Why does it always returns DBNull")
Else : Response.Write(cmd.Parameters("#returnValue").Value.ToString())
End If
connect.Close()
Here is the SQL code
ALTER PROCEDURE [dbo].[saveAccess]
(#Name NVARCHAR(20), #returnValue INT OUTPUT )
AS
BEGIN
INSERT INTO Access ([Name]) VALUES (#Name);
SELECT #returnValue = ##ROWCOUNT;
END
Not sure what is the silly mistake that I am doing. Any input helps.
Thanks
Instead of SELECT, try using SET to set the value of the output parameter
SET #returnValue = ##ROWCOUNT;
Solution (as said silly myself): missed the # symbol in front of the returnValue variable. I typed up the code in this posting correctly but I had it without the # in the SP.
wrong: SELECT returnValue = ##ROWCOUNT;
correct: SELECT #returnValue = ##ROWCOUNT;
Thanks
I have the below code which is populating a dropdownlist in ASP.NET. When I use a single value, everything works like a charm, but I want the DataTextField to use two fields coming from the database, not one. Any assistance would be greatly appreciated. I have tried several ways, but nothing seems to work :(
Dim connstr As String = Session("ConnStrEP")
Using con As New SqlConnection(connstr)
Using cmd As New SqlCommand()
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "GetWaivers"
cmd.Connection = con
con.Open()
Dim dr As SqlDataReader = cmd.ExecuteReader()
dr.Read()
Code.DataSource = dr
Code.DataTextField = String.Format("{0}, {1}", Code.SelectedValue("tblWVCode").ToString(), Code.SelectedValue("tblWVDesc").ToString())
Code.DataValueField = "tblWVDesc"
Code.DataBind()
dr.Close()
con.Close()
End Using
End Using
UPDATE:
I generated the below SQL, but I am receiving an error when I execute the SQL Server 2008 Stored Procedure. "Invalid operator for data type. Operator equals add, type equals ntext.
"
SELECT TblWvCode, TblWvDesc, (TblWvCode + ' - ' + TblWvDesc) As FullList FROM EP.dbo.WaiverVarianceTbl
Modify the stored proc to concatenate the tblWVCode and tblWVDesc values and return them in a new field, you can then use that field for the DataTextField
You can't do that, you'll need to change your SQL query to return the field on the format you need. DataTextField must be a field or property name.
Your query should looks like this
SELECT
TblWvCode,
TblWvDesc,
(
CAST(TblWvCode as nvarchar(max)) + ', ' + CAST(tblWVDesc as nvarchar(max))
) as FullList
FROM EP.dbo.WaiverVarianceTbl
and then your VB code would be something like this
Code.DataTextField = "FullList"
Code.DataValueField = "tblWVDesc"
I am working on a Tag system for a news page designed in ASP.NET. For the system I require a TagExists method to check for tags within the database. The stored procedure I have written is below.
ALTER PROCEDURE [dbo].[Tags_TagExists](
#Tag varchar(50))
AS
BEGIN
If (EXISTS(SELECT * FROM dbo.Tags WHERE LOWER(#Tag) = LOWER(Tag)))
RETURN 1
ELSE
RETURN 0
END
When I call this method however 0 is always returned. I am using the following code to call the method
Public Shared Function TagExists(ByVal name As String) As Boolean
Dim result As Boolean
Using conn As SqlConnection = New SqlConnection(ConnectionString)
Dim cmd As New SqlCommand("Tags_TagExists", conn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#Tag", name)
conn.Open()
result = Convert.ToBoolean(cmd.ExecuteScalar())
conn.Close()
End Using
Return result
End Function
I have tried switching the procedure to return 0 if the tag exists and 1 if it does not and it still returns 0 despite the exact same testing conditions. I have also returned the actual select query and it has complained of the Tag "news" (my test item) not being an int on execution showing the select itself is definitely properly formed.
If anyone can shed some light on this, Thanks
Michael
It should probably be a function, but here is the stored proc code:
ALTER PROCEDURE [dbo].[Tags_TagExists](
#Tag varchar(50))
AS
BEGIN
If EXISTS(SELECT 1 FROM dbo.Tags WHERE LOWER(#Tag) = LOWER(Tag))
BEGIN
SELECT 1
END
ELSE
BEGIN
SELECT 0
END
END
You're returning from a Stored Procedure, not getting a single scalar value from a SQL statement.
I'm assuming this is a simple example and you have other processing you want to handle inside the Stored Procedure. In that case, using the Stored Procedure and return value is the right way to go. You need to handle the return value from the Stored Procedure in your C# code (Please excuse any syntax errors, my VB.NET is a bit rusty):
Public Shared Function TagExists(ByVal name As String) As Boolean
Dim result As Boolean
Using conn As SqlConnection = New SqlConnection(ConnectionString)
Dim cmd As New SqlCommand("Tags_TagExists", conn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#Tag", name).
Dim retVal As SqlParameter = _
cmd.Parameters.Add("return_value", SqlDbType.Int)
retval.Direction = ParameterDirection.ReturnValue
conn.Open()
cmd.ExecuteNonQuery()
result = System.Convert.ToBoolean(retval.Value)
conn.Close()
End Using
Return result
End Function
If you're strictly interested in the return value and your Stored Procedure isn't performing any other use, then convert it to a simple select statement (or function). Your use of ExecuteScalar would work in that case.
Please try using SELECT 1 and SELECT 0 instead of RETURN statement
Hope that helps,
I have made stored procedures in oracle.
I'm calling it through my asp.net code.
The procedure is :
PROCEDURE prc_GetNewQuestionNo(iNextQuestionNo IN OUT NUMBER)
IS
iQuestionNo NUMBER ;
BEGIN
Select MAX(QUESTIONNO)+ 1 INTO iQuestionNo
from tblIFFCOQUESTIONMASTER;
iNextQuestionNo:=iQuestionNo;
END prc_GetNewQuestionNo;
and I'm calling it in asp.net:
<Connection>
com.CommandType = CommandType.StoredProcedure;
com.CommandText = StoredProcedures.GET_NEW_QUESTION_NO;
com.Parameters.Add(new OracleParameter("iNextQuestionNo", OracleType.Number)).Direction = ParameterDirection.InputOutput;
adp = new OracleDataAdapter(com);
ds = new DataSet();
adp.Fill(ds);
How to get its return value?
Isn't it better to use function? Just like:
create function prc_GetNewQuestionNo(iNextQuestionNo IN NUMBER)
return number AS
iQuestionNo NUMBER ;
BEGIN
Select MAX(QUESTIONNO)+ 1 INTO iQuestionNo from tblIFFCOQUESTIONMASTER;
return iQuestionNo;
END prc_GetNewQuestionNo;
I wanted to add a comment/question to your reply there Paul, but I couldnt. Apologize for my ignorance, but if you are using a SQL Server stored procedured with isolation level serializable, arent supposed all the sql tables to be locked for the time the transaction/stored procedure last, giving no problems of concurrency? is this a bad practice?
I guess the problem is here
adp = new OracleDataAdapter(com);
ds = new DataSet();
adp.Fill(ds);
You want a scalar value and not an entire record set.. right? So instead try like this
//some code snippet
db.ExecuteNonQuery(cmd);
iNextQuestionNo= (decimal?)cmd.Parameters[0].Value;
Hope this helps