How to get output parameter of sql in codebehind - asp.net

My stored procedure is like this.
ALTER PROCEDURE [dbo].[GetImagesByDesignId]
#DesignID bigint,
#RegID bigint,
#PageIndex INT,
#NumRows INT,
#ImageCount INT OUTPUT
AS
BEGIN
SELECT #ImageCount=(SELECT COUNT(*) FROM DocManagement where DesignID=#DesignID and RegID=#RegID)
Declare #startRowIndex INT;
set #startRowIndex = (#PageIndex * #NumRows) + 1;
With ImageEntries as (
SELECT ROW_NUMBER() OVER (ORDER BY DocumentID ASC) as Row, RegID, DesignID,ImageName
FROM DocManagement
WHERE DesignID=#DesignID and RegID=#RegID
)
Select RegID, DesignID,ImageName
FROM ImageEntries
WHERE Row between
#startRowIndex and #StartRowIndex+#NumRows-1
END
I am calling storedprocedure in my codebehind as
Dim dt As DataTable = objUpload.GetDocuments(lngRegID, lngDesignID)
dlView.DataSource = dt
dlView.DataBind()
dlView is datalist.Method GetDocuments is written in another class like this
Public Function GetDocuments(ByVal lngRegID As Long, ByVal lngDesID As Long) As DataTable
Try
Dim db As Database = DatabaseFactory.CreateDatabase()
Dim DbCommand As DbCommand = db.GetStoredProcCommand("GetImagesByDesignId")
db.AddInParameter(DbCommand, "#RegID", DbType.Int64, lngRegID)
db.AddInParameter(DbCommand, "#DesignID", DbType.Int64, lngDesID)
db.AddInParameter(DbCommand, "#PageIndex ", DbType.Int32, intPageIndex)
db.AddInParameter(DbCommand, "#NumRows ", DbType.Int32, intNumRows)
db.AddOutParameter(DbCommand, "ImageCount", DbType.Int32, 250)
Return db.ExecuteDataSet(DbCommand).Tables(0)
Dim strOutput() As String = {db.GetParameterValue(DbCommand, "ImageCount").ToString}
Catch ex As Exception
End Try
End Function
Problem is i want to get datattable as well as imagecount in codebehind.How can i return back datatable and imagecount to codebehind.Can anybody help?

You can create a class to use are return value that holds both the data table and the image count. Or you can send a variable as an argument by reference:
Public Function GetDocuments(ByVal regID As Long, ByVal desID As Long, ByRef imageCount As Integer) As DataTable
In the method you just set the value of imageCount.
In your stored procedure you don't need a nested query to get the count. Just do like this:
select #ImageCount = count(*)
from DocManagement
where DesignID = #DesignID and RegID = #RegID
Note:
I see that you have a Catch block without anything in it. Never ever do that. You are catching exceptions and ignoring them, that can only lead to problems.
In there rare case where you actually need to catch an exception and ignore it, you should at least have a comment inside the Catch block explaining why it's ignored.
Also, you are catching the base class Exception, when you should catch a more specific class like SqlException.

Public Function GetDocuments(ByVal lngRegID As Long, ByVal lngDesID As Long, ByRef strOutput As String) As DataTable
You can use ByRef and pass a string variable as a reference and set it in your method. The reference of strOutput will be passed to your method, and when you set the value of that variable in the method you can get back the changed value after the method call.
Dim strOutput As String = Nothing
Dim dt As DataTable = GetDocuments(lngRegID, lngDesID, strOutput)
Console.WriteLine(strOutput)

Related

How to select GUID column by another GUID column in VB.net?My Select query does not work

I am new to programming and get the chance to work and maintain in another developers project.
The project is built with ASP.Net Vb.Net and SQl Server.
I am trying to select the primary key ID (which is actually a GUID) from a table.
SQID = Core.DB.GetString("SELECT id FROM SQC WHERE sid = " & sid)
In the Table SQC the primary key is id which is guid and the sid is also guid which is primary key to another table.
my previous developer developed the code to select string variable GetString function where GetString is
Shared Function GetString(ByVal selectQueryText As String, ByVal ParamArray params As SqlParameter()) As String
Dim dt As DataTable = Nothing
Try
dt = GetData(selectQueryText, CommandType.Text, params)
If dt.Rows.Count = 0 Then
Return ""
Else
If TypeOf dt.Rows(0)(0) Is DBNull Then
Return ""
Else
Return CStr(dt.Rows(0)(0))
End If
End If
Finally
If dt IsNot Nothing Then dt.Dispose()
End Try
End Function
When I debug the code my process enters into GetString Function and from Get String it goes to GetData function
Shared Function GetData(ByVal selectCommandText As String, ByVal selectCommandType As CommandType, ByVal ParamArray params As SqlParameter()) As DataTable
Dim conn As SqlConnection = Nothing
Try
conn = GetOpenSqlConnection()
Return GetData(conn, selectCommandText, selectCommandType, params)
Finally
If conn IsNot Nothing Then conn.Dispose()
End Try
End Function
Shared Function GetData(ByVal conn As SqlConnection, ByVal selectCommandText As String, ByVal selectCommandType As CommandType, ByVal ParamArray params As SqlParameter()) As DataTable
If conn Is Nothing Then Return GetData(selectCommandText, selectCommandType, params)
Dim sa As SqlDataAdapter = Nothing
Try
sa = New SqlDataAdapter(selectCommandText, conn)
sa.SelectCommand.CommandType = selectCommandType
Dim dt As New DataTable
Try
For Each param As SqlParameter In params
sa.SelectCommand.Parameters.Add(param)
Next
sa.Fill(dt)
Return dt
Catch ex As Exception
dt.Dispose()
Throw ex
End Try
Finally
If sa IsNot Nothing Then sa.Dispose()
End Try
End Function
In the Try Catch area of exeption handling the code breaks and throws the exception error. It saying Incorrect syntax near 'a379'. which is first the part of sid (GUID). I mean the sid value is 9417A379-6371-432F-9DA5-BCFC46DD95A1
I am not sure how to handle this. I want to select the id from from SQC table and store it in a variable.
I am looking for your advice and suggestion. As I am new in the programming world please also point me my mistakes.
Thanks
It looks like your issue could be fixed like so:
SQID = Core.DB.GetString("SELECT id FROM SQC WHERE sid = '" & sid & "'")
But you should be aware that this style of code is open to SQL injection and you may want to look at ways of parameterising your queries (i.e. don't take what's in this project as good practice).

How to store the value of last inserted id(PK) into a variable where the primary key is a GUID in VB.Net

My question is related to the question asked in here How to get last inserted id?
But the scope_identity() will not work for me as in my case the primary key value for the table is a GUID value.
Also I have seen the question in here
SQL Server - Return value after INSERT
but the link does not explain how can i store the value in a variable. I need to store the value in a variable which I can use for multiple entry.
I am inserting hard coded value into multiple SQL Server tables. All the primary key columns are GUID.
The table structure are as follows.
This is the code I use to insert data into survey table.
Protected Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim survey = Guid.NewGuid().ToString()
Dim SurveyTitle As String = "Diversity Monitoring Survey"
Dim SurveyDetail As String = ""
Core.DB.DoQuery("insert into survey(id,title, detail,employerid,userid) values(#id,#title, #detail, #eid, #uid);", Core.DB.SIP("title", SurveyTitle), Core.DB.SIP("detail", SurveyDetail), Core.DB.SIP("eid", LocalHelper.UserEmployerID()), Core.DB.SIP("uid", LocalHelper.UserID()), Core.DB.SIP("id", survey))
End Sub
Where DoQuery is
Shared Sub DoQuery(ByVal commandText As String, ByVal ParamArray params As SqlParameter())
Dim conn As SqlConnection = Nothing
Try
conn = GetOpenSqlConnection()
DoQuery(conn, commandText, params)
Finally
If conn IsNot Nothing Then conn.Dispose()
End Try
End Sub
Now I want to retrieve of just inserted SurveyId value and store it into a variable strSurveyId
Dim strSurveyID As String
So that I can insert that value in the table SurveyQuestionCategory:
Core.DB.DoQuery("insert into surveyquestioncategory(title, detail, surveyid) values(#title, #detail, #sid)", Core.DB.SIP("title", strSurveyQuestionCategoryTitle), Core.DB.SIP("detail", strSurveyQuestionCategoryDetail), Core.DB.SIP("sid", strSurveyID))
scope_identity() will not work in my case as the the is GUID.
I have tried this
SELECT * from [MPBlLiteDev].[dbo].[Survey] where id=SCOPE_IDENTITY()
But it gives me a error
Operand type clash: uniqueidentifier is incompatible with numeric
Please suggest with code.
Please go through the below stored procedure
Create proc SPInsertSurvey
(
#Title varchar(MAX),
#OutSurveyID UNIQUEIDENTIFIER output
)
as
DECLARE #Table TABLE (SurveyID UNIQUEIDENTIFIER)
begin
insert into survey(Title)
Output inserted.SurveyID into #Table values (#Title)
set #OutSurveyID =(select SurveyID from #Table)
end
You can execute it by using below Syntax
DECLARE #return_value int,
#OutSurveyID uniqueidentifier
EXEC #return_value = [dbo].[SPInsertSurvey]
#Title = N'''S1''',
#OutSurveyID = #OutSurveyID OUTPUT
SELECT #OutSurveyID as N'#OutSurveyID'
SELECT 'Return Value' = #return_value
Hope this will help
SCOPE_IDENTITY() will only return the newly generated Identity value if there is any, for GUID values you would need a table variable with OUTPUT clause in your insert statement something like this.....
DECLARE #NewIDs TABLE (ID UNIQUEIDENTIFIER)
insert into survey(id,title, detail,employerid,userid)
OUTPUT inserted.id INTO #NewIDs(ID)
values(#id,#title, #detail, #eid, #uid);
SELECT * FROM #NewIDs

Convert Dataset into String in VB

I am having an error with compiling the codes. It says that dataset cant be converted to string.. Please help me.. I have done this by using SQL Stored procedure.. I have to get the employee name saved in master table to retrieve the ID and then ID should retrieve the leave details from leave details table.
Public Shared Function GetEmpID(ByVal EmpName As String) As DataSet
Dim db As Database = DatabaseFactory.CreateDatabase(HttpContext.Current.Session("CompanyID").ToString) ' TO Get Database Connection
Dim dbCommand As DbCommand = db.GetStoredProcCommand("spRetrieveEmpID") ' Stored Procedure to Execute
db.AddInParameter(dbCommand, "EmployeeName", DbType.String, EmpName) ' Parameter for Stored Procedure
Return db.ExecuteDataSet(dbCommand) ' Execute Stored Procedure
End Function
Public Shared Function EmpLeaveDetails(ByVal EmployeeID As String) As DataSet
Dim db As Database = DatabaseFactory.CreateDatabase(HttpContext.Current.Session("CompanyID").ToString) ' TO Get Database Connection
Dim dbCommand As DbCommand = db.GetStoredProcCommand("spHRLeaveEntitlement") ' Stored Procedure to Execute
db.AddInParameter(dbCommand, "EmployeeID", DbType.String, EmployeeID) ' Parameter for Stored Procedure
Return db.ExecuteDataSet(dbCommand) ' Execute Stored Procedure
End Function
And this is my leave.aspx.vb codes
Private Sub ddlEmpName_SelectedIndexChanged(ByVal sender As Object, ByVal e As Telerik.Web.UI.RadComboBoxSelectedIndexChangedEventArgs) Handles ddlEmpName.SelectedIndexChanged
EmployeeID = TESTING.GetEmpID(ddlEmpName.Text)
If ds.Tables(0).Rows.Count > 0 Then
dgLeaveDetails.DataSource = ds
dgLeaveDetails.DataBind()
End If
ds1 = TESTING.EmpLeaveDetails(EmployeeID)
dgLeaveDetails.DataSource = ds1
ddlEmpName.SelectedIndex = -1
dgLeaveDetails.Rebind()
End Sub
The line
EmployeeID = TESTING.GetEmpID(ddlEmpName.Text)
looks like the problem to me.
You should use:
Dim dst As Dataset = TESTING.GetEmpID(ddlEmpName.Text)
EmployeeID = CStr(dst.Tables(0).Rows(0).Item("EmployeeID"))
You are setting EmployeeID, like this:
EmployeeID = TESTING.GetEmpID(ddlEmpName.Text)
The GetEmpID method returns a DataSet object. Therefore, EmployeeID references a DataSet, rather than equaling a single ID value. Later, you try to pass EmployeeID to the EmpLeaveDetails method like this:
ds1 = TESTING.EmpLeaveDetails(EmployeeID)
However, the EmpLeaveDetails method takes a String as a parameter. Therefore, you are trying to pass a DataSet into a method that expects a String. Since DataSet objects cannot be automatically converted to the String type, the compiler gives the error.
To fix it, you need to either have the GetEmpID return a string, or else you need to retrieve the single string value from the DataSet before passing it to the EmpLeaveDetails method.

SqlCommand placeholder parameters: "Incorrect syntax near '?'" and "Must declare the scalar variable #param"?

I am developing a web mapping application intranet for our company. I am creating an "add polygon" function on the map. I use AspMap, VB.NET and SQL Server. When a user clicks a button to add a new record from the web form input data attribute, the error Incorrect syntax near '?' occurs.
My code is:
Private Sub AddNewShape(ByVal checklist_id As String, ByVal type As String, ByVal shape As AspMap.Shape, ByVal address_area As String, ByVal dmz As String, ByVal customerid As String, ByVal source As String, ByVal area As String, ByVal instalatur As String, ByVal developer As String, ByVal data_received As DateTime, ByVal doc_data As DateTime, ByVal datereport As DateTime, ByVal remark As String)
Dim tableName As String
Select Case shape.ShapeType
Case AspMap.ShapeType.Line
tableName = "lines"
Case AspMap.ShapeType.Polygon
tableName = "sambungan_baru"
Case Else
Return
End Select
Dim conn As SqlConnection = GetDbConnection()
Dim sql As String = "INSERT INTO " & tableName & " (CHECKLIST_ID, TYPE, SHAPEDATA, ADDRESS_AREA, DMZ, CUSTOMERID, SOURCE, AREA, INSTALATUR, DEVELOPER, DATA_RECEIVED, DOC_DATA, DATA_SENT, REMARK) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
Dim cmd As SqlCommand = New SqlCommand(sql, conn)
cmd.Parameters.AddWithValue("CHECKLIST_ID", checklist_id)
cmd.Parameters.AddWithValue("TYPE", type)
cmd.Parameters.AddWithValue("SHAPEDATA", shape.ShapeData)
cmd.Parameters.AddWithValue("ADDRESS_AREA", address_area)
cmd.Parameters.AddWithValue("DMZ", dmz)
cmd.Parameters.AddWithValue("CUSTOMERID", customerid)
cmd.Parameters.AddWithValue("SOURCE", source)
cmd.Parameters.AddWithValue("AREA", area)
cmd.Parameters.AddWithValue("INSTALATUR", instalatur)
cmd.Parameters.AddWithValue("DEVELOPER", developer)
cmd.Parameters.AddWithValue("DATA_RECEIVED", data_received)
cmd.Parameters.AddWithValue("DOC_DATA", doc_data)
cmd.Parameters.AddWithValue("DATA_SENT", datereport)
cmd.Parameters.AddWithValue("REMARK", remark)
cmd.ExecuteNonQuery()
conn.Close()
ReloadShapesDatabase()
End Sub
I changed this:
Dim sql As String = "INSERT INTO " & tableName & " (CHECKLIST_ID, TYPE, SHAPEDATA, ADDRESS_AREA, DMZ, CUSTOMERID, SOURCE, AREA, INSTALATUR, DEVELOPER, DATA_RECEIVED, DOC_DATA, DATA_SENT, REMARK) VALUES *(?,?,?,?,?,?,?,?,?,?,?,?,?,?)
to this:
Dim sql As String = "INSERT INTO " & tableName & " (CHECKLIST_ID, TYPE, SHAPEDATA, ADDRESS_AREA, MZ, CUSTOMERID, SOURCE, AREA, INSTALATUR, DEVELOPER, DATA_RECEIVED, DOC_DATA, DATA_SENT, REMARK)(#checklist_id, #type, #shapedata, #address_area, #dmz, #conection, #source, #area, #instalatur, #developer, #data_received, #doc_data, data_sent, #remark)"
And I run into the alert: Must declare the scalar variable "#conection". Can anyone help me?
You are confusing two different styles of parameters in SQL queries. The ODBC syntax uses simple placeholder '?' character for each parameter, and the parameters are replaced in the same order that you add them to the parameters collection. For an OdbcCommand, the name you give the parameters is ignored, and only their sequence matters.
For a SqlCommand, the parameter names are meaningful; when the command executes, it will be run through a SQL Stored procedure that takes a list of parameter names and values and substitutes them into the T-SQL query. In this case, the order you add parameters to your query isn't important, but you need to make sure the names are correct (including the "#" prefix.)
The proper way to use a SqlCommand with parameters is as follows:
// The SQL Query: Note the use of named parameters of the form
// #ParameterName1, #ParameterName2, etc.
Dim sql As String = "INSERT INTO " & tableName & _
" (CHECKLIST_ID, TYPE, SHAPEDATA ) " & _
"VALUES " & _
" (#ChecklistId, #Type, #ShapeData )"
// The Parameter List. Note that the Parameter name must exactly match
// what you use in the query:
Dim cmd As SqlCommand = New SqlCommand(sql, conn)
cmd.Parameters.AddWithValue("#CheckListId", checklist_id)
cmd.Parameters.AddWithValue("#Type", type)
cmd.Parameters.AddWithValue("#ShapeData", shape.ShapeData)
cmd.ExecuteNonQuery()
You should assign parameters like this and in your case you missed providing value for "CONECTION" parameter. Also as an additional note, you should always enclose connection objects in using blocks. See this and look at the "Remarks" section.
command.CommandText = "INSERT INTO Table (Col1, Col2, Col3) VALUES _
(#Col1Val, #Col2Val, #Col3Val)"
command.Parameters.AddWithValue("#Col1Val","1");
command.Parameters.AddWithValue("#Col2Val","2");
command.Parameters.AddWithValue("#Col3Val","3");
Please make sure that Dim cmd As SqlCommand = New SqlCommand(sql, conn) uses conn with an open connection.
Then verify your parameters type to be in accordance with the database table definition. Plus, If your using string type you may add an ' before and after any text inserted.
To be sure, you can break on cmd.ExecuteNonQuery() and copy the value of the command associated and running it to any SQL manager tool.
Finally, dispose your cmd.
Otherwise check if this is helpful for your issue : http://social.msdn.microsoft.com/Forums/en-US/sqlspatial/thread/9d75106a-b0d4-49cc-ac86-d41cba4ab797

IF EXISTS IN STORED PROCEDURE

I am using following storedprocedure
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
Alter PROCEDURE [dbo].[GetUserDetailsByUserID]
(
#UserId varchar(100)
)
AS
BEGIN
IF EXISTS(Select * from Registration where UserId=#UserID)
BEGIN
Select
[Name],
[UserId],
[PermanentAddress],
[TemporaryAddress],
[OfficePhoneNo],
[ResidentialPhoneNo],
[MobileNo],
[Email],
[ContactPerson],
[C_OfficePhoneNo],
[C_ResidentialPhoneNo],
[C_MobileNo],
[C_Email],
[Project],
[TotalAmount]
From
Registration
Where
UserId=#UserId
END
END
I am using following code in vb
Public Function GetUserDetailsByUserID(ByVal strUserId As String) As DataTable
Try
Dim db As Database = DatabaseFactory.CreateDatabase()
Dim DbCommand As DbCommand = _
db.GetStoredProcCommand("GetUserDetailsByUserID")
db.AddInParameter(DbCommand, "#UserId", DbType.String, strUserId)
Return db.ExecuteDataSet(DbCommand).Tables(0)
Catch ex As Exception
Return New DataTable()
End Try
End Function
If details corresponding to userid does not exist in registration table, db.ExecuteDataSet(DbCommand).Tables(0) shows one error as cannot find Table(0). What modification in stoted procedure i hve to make to get rid of this error?
You can simply get rid of the IF EXISTS. When the record doesn't exist, you will get an empty table (which I think is what you want, looking at your sample code)
The procedure will not always return a record set. If there is no record set then Tables will be empty and Tables(0) will fail and return an error. You should just return the selection rather than only selecting if the record exists. Your code can then check for an empty returned record set.
In the VB code, change
Return db.ExecuteDataSet(DbCommand).Tables(0)
to
Dim Ds as DataSet = db.ExecuteDataSet(DbCommand)
If Ds.Tables.Count = 1 Then
Return Ds.Tables(0)
Else
Return New DataTable()
End If
Also, remove the If Exists from the Stored Procedure, since if the row exists, you will force the database to search twice in the table for the record where UserId=#UserID.

Resources