get return value from stored procedure without output parameter - vb.net

I have a vb.net application that inserts records into a db table using a stored procedure that is supposed to return a value. This stored procedure was setup by someone else and initially was linked to a webservice through which my application made the insert and got the return value in the returned xml. I now have access to the db table and not sure how to receive the return value in my vb.net method.
SQl stored procedure snippet;
#urlname varchar(500),
#siteid varchar(16),
#origin varchar(50),
#queryid varchar(25)
AS
SET NOCOUNT ON;
declare #cnt int
declare #serverip varchar(16)
declare #mincnt int
declare #siteservercnt int
select #cnt=COUNT(*) from sites
where urlname=#urlname
if #cnt = 0
begin
insert into sites (urlname,siteid,exported,origin,queryid)
values(#urlname,#siteid,1,#origin,#queryid)
select #siteservercnt = COUNT(*) from siteserverip where siteid=#siteid
if #siteservercnt=0
begin
select top 1 #mincnt=COUNT(*),#serverip=serverip from siteserverip
group by serverip
order by COUNT(*)
select top 1 #mincnt=sitecount,
#serverip=serverip from serveripcounts
order by sitecount
insert into siteserverip values(#siteid,#serverip)
update serveripcounts set sitecount=sitecount+1
where serverip=#serverip
end
end
SELECT siteid from sites
where urlname=#urlname
return
and my vb.net code to do the insert
CommandObj.CommandText = "Getsite"
CommandObj.CommandTimeout = 90
Dim newUrl As String = String.Empty
CommandObj.Parameters.Clear()
Dim m_param As SqlParameter
m_param = CommandObj.Parameters.Add("#urlname", SqlDbType.VarChar, 500)
m_param.Direction = ParameterDirection.Input
m_param.Value = name
m_param = CommandObj.Parameters.Add("#siteid", SqlDbType.VarChar, 16)
m_param.Direction = ParameterDirection.Input
m_param.Value = siteid
m_param = CommandObj.Parameters.Add("#origin", SqlDbType.VarChar, 50)
m_param.Direction = ParameterDirection.Input
m_param.Value = method
m_param = CommandObj.Parameters.Add("#queryId", SqlDbType.VarChar, 25)
m_param.Direction = ParameterDirection.Input
m_param.Value = forumID
Dim recordsAffected As Integer = CommandObj.ExecuteNonQuery

You can use ExecuteScalar to get that value. ExecuteNonQuery returns number of rows affected while you want to get the value generated by last select. You could use ExecuteReader as well but that is useful when your SP might be returning more columns and/or more rows.
'Populate first column and first row value in siteID
Dim siteID As Integer = CommandObj.ExecuteScalar

Related

sql procedure returns 1 but vb.net gets 0

I have stored procedure which seems to be working fine when executing directly from management studio, but when it comes o vb.net code i always get 0. Can anyone look at that and tell me what is missing here. I read documentation and seems that should work as expected however it is not somehow.
stored procedure:
ALTER PROCEDURE [dbo].[IsPhraseConnectedAlready]
#PhraseId INT,
#KatSubkatId INT,
#WordId INT,
#SubsubkatId INT = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #temp_T_Html_Word_Categories TABLE(Id INT)
DECLARE #temp_T_Html_WordCat_Phrase TABLE(FK_Phrase_ID INT)
DECLARE #temp_T_Html_Phrase TABLE(Id INT, [Name] varchar(max))
IF #SubsubkatId IS NULL
BEGIN
INSERT INTO #temp_T_Html_Word_Categories(Id) SELECT Id FROM T_Html_Word_Categories WHERE FK_KatSubkat_ID = #KatSubkatId And FK_Word_ID = #WordId And FK_Subsubkat_ID IS NULL;
END
ELSE
BEGIN
INSERT INTO #temp_T_Html_Word_Categories(Id) SELECT Id FROM T_Html_Word_Categories WHERE FK_KatSubkat_ID = #KatSubkatId And FK_Word_ID = #WordId And FK_Subsubkat_ID = #SubsubkatId;
END
Declare #Id int;
Select #Id = Id From #temp_T_Html_Word_Categories;
INSERT INTO #temp_T_Html_WordCat_Phrase(FK_Phrase_ID) SELECT FK_Phrase_ID FROM T_Html_WordCat_Phrase WHERE FK_Word_Categorie_ID = #Id;
IF (##ROWCOUNT > 0)
BEGIN
Declare #FK_Phrase_ID int;
--it makes no difference what you SELECT in an EXISTS sub-query as it is just syntactical sugar. (ie Nothing is actually selected.) SELECT * or SELECT 1 ...
WHILE EXISTS(SELECT * FROM #temp_T_Html_WordCat_Phrase)
BEGIN
Select Top 1 #FK_Phrase_ID = FK_Phrase_ID From #temp_T_Html_WordCat_Phrase;
INSERT INTO #temp_T_Html_Phrase(Id, [Name]) SELECT Id, [Name] FROM T_Html_Phrase WHERE Id = #FK_Phrase_ID;
IF (#PhraseId = #FK_Phrase_ID)
RETURN 1
Delete #temp_T_Html_WordCat_Phrase Where FK_Phrase_ID = #FK_Phrase_ID;
END;
END
ELSE
BEGIN
Delete #temp_T_Html_Word_Categories;
RETURN 0
END
RETURN 0
END
This is my visual basic.net code below:
Public Function IsPhraseConnectedAlready(phraseId As Integer, katsubkatid As Integer, wordid As Integer, subsubkatid As Integer?) As Integer
Using con As New SqlConnection(_strcon)
Using cmd As New SqlCommand("IsPhraseConnectedAlready", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#PhraseId", phraseId)
cmd.Parameters.AddWithValue("#KatSubkatId", katsubkatid)
cmd.Parameters.AddWithValue("#WordId", wordid)
If subsubkatid.HasValue Then 'check whether nullable field contain value
cmd.Parameters.AddWithValue("#SubsubkatId", subsubkatid.Value)
Else
cmd.Parameters.AddWithValue("#SubsubkatId", DBNull.Value)
End If
con.Open()
Dim i = CType(cmd.ExecuteScalar(), Integer)
If i = 1 Then
Return True
ElseIf i = 0 Then
Return False
End If
End Using
End Using
End Function
Executed from ssms directly shows it reaches RETURN 1, however with same values passed from vb.net i am getting 0:
in vb.net working with same values:
seems the resolution was to do like this:
instead of this:
RETURN 1 or RETURN 0
make it as:
SELECT 1 or SELECT 0
however to break execution when it reaches first select to add additional return after each SELECT.
Does anyone sees any issues with that? To me it works and wonder why just RETURN was not from vb.net
cmd.ExecuteScalar() will execute the query, and return the first column of the first row in the result set returned by the query. However, you're not returning a column/row, you're just returning a value.
So, either convert RETURN 1 to SELECT 1 or else declare a return parameter in your VB.Net code like so:
...
Dim returnParameter As SqlParameter = cmd.Parameters.Add("#ReturnVal", SqlDbType.Int)
returnParameter.Direction = ParameterDirection.ReturnValue
con.Open()
cmd.ExecuteNonQuery()
Dim i = CType(returnParameter.Value, Integer)
...

Fetch stored procedure value

I have a table RhSeq which contains the following columns:
ScoTable (PK, varchar(20),not NULL)
ScoColonne (PK, varchar(50), not NULL)
ScoSequence (int, not NULL)
ScoDescription (varchar(100), not NULL)
I have a stored procedure which, given ScoTable and ScoColonne, increments ScoSequence and returns the incremented ScoSequence value:
EDITED - Here's the full stored procedure
CREATE PROCEDURE [dbo].[usp_RhSeqNextVal]
#table VARCHAR (20), #colonne VARCHAR (30), #sequence_id INT OUTPUT
AS
SET NOCOUNT ON
SET #sequence_id = -1
DECLARE #transaction AS BIT
SET #transaction = 0;
IF 0 = ##TRANCOUNT
BEGIN
BEGIN TRAN
SET #transaction = 1;
END
UPDATE dbo.RhSeq
SET ScoSequence = CASE WHEN Right(#colonne,1) = '-' THEN
ScoSequence - 1
ELSE
ScoSequence + 1
END
WHERE ScoTable = #table
AND ScoColonne = #colonne
SELECT #sequence_id = ScoSequence
FROM dbo.RhSeq
WHERE ScoTable = #table
AND ScoColonne = #colonne
IF 1 = #transaction
BEGIN
COMMIT TRAN
END
In Visual Studio, if I right click on the stored procedure (in Server Explorer) and choose 'Execute', I enter values for ScoTable and ScoColonne and set sequence_id to null and it executes fine, returning the new incremented sequence_id value. So no problem with the stored procedure.
The problem I have is when I try to get the returned sequence_id inside my code.
SqlParameter param1 = new SqlParameter("#ScoTable", "MyTable");
SqlParameter param2 = new SqlParameter("#ScoColonne", "MyColumn");
SqlParameter param3 = new SqlParameter("#sequence_id", DBNull.Value);
var numeroSequence = db.Database.SqlQuery<RhSeq>("usp_RhSeqNextVal #ScoTable,#ScoColonne, #sequence_id", param1, param2,param3).ToList();
I get an error
System.Data.Entity.Core.EntityCommandExecutionException: A member of the type, 'ScoTable', does not have a corresponding column in the data reader with the same name
From my understanding, the error comes from RhSeq, since the stored procedure returns only sequence_id, which is an int, it cannot create a RhSeq object with it. I try to cast the result to an int, but it's still not working.
How can I store the sequence_id returned by the stored procedure into my var numeroSequence?
Had a similar issue in LinqToSQL. Selecting #sequence_id in the procedure after setting it did the job:
In your SP after:
SELECT #sequence_id = ScoSequence
FROM dbo.RhSeq
WHERE ScoTable = #table
AND ScoColonne = #colonne
Add:
SELECT #sequence_id
And then of course:
db.Database.SqlQuery<int>...

how to get the auto generated values from sql using c#?

I have an Stored Procedure like below..
CREATE PROCEDURE [dbo].[spMYSPDetails]
#Id VarChar(6),
#Name VarChar(50),
#Limit Money,
#Status VarChar(1),
#Accounts As SmallInt
AS BEGIN
IF(LEN(ISNULL(#strDebtorId, '')) = 0) BEGIN
WHILE 0 = 0 BEGIN
SET #Id = '9' + dbo.fnGenerateRandomCode(5, '0123456789')
IF NOT EXISTS (SELECT 1 FROM mytbl WITH (NOLOCK) WHERE s_Id = #Id) BEGIN
INSERT INTO Mytbl
(D_Id,
D_Name,
D_Limit,
D_Status,
D_Accounts,
D_dtmStamp,
D_Balance)
VALUES
(#Id,
#Name,
#Limit,
#Status,
#Accounts,
GETDATE(),
#Limit)
BREAK
END
I have c# sharp code to call this SP like this...
try
{
string Id = "";
if (hdDId.Value.ToString() != "")
{
Id = hdDId.Value.ToString();
}
objDB.blnParamClear();
objDB.blnParamAdd(ParameterDirection.Input, "#Id", SqlDbType.VarChar, 6, Id.ToString());
objDB.blnParamAdd(ParameterDirection.Input, "#Name", SqlDbType.VarChar, 50, txtName.Value.ToString());
objDB.blnParamAdd(ParameterDirection.Input, "#Limit", SqlDbType.Money, 8, decimal.Parse(txtLimit.Value.ToString()));
objDB.blnParamAdd(ParameterDirection.Input, "#Status", SqlDbType.VarChar, 1, cboStatus.Value);
objDB.blnParamAdd(ParameterDirection.Input, "#intMaxAccounts", SqlDbType.SmallInt, 4, txtAccnts.Value.ToString());
blnResult = (objDB.lngExecuteSP("spMYSPDetails") == 0);
}
Now I want to catch that auto generated(random) ID in C# for my reference. I tried but am unable to Catch.. Is there any way to catch the same id that is generated by SP in SQL.Suggest me something...
Use your #ID as output variable.
#Id VarChar(6) output
Then set your C# parameter
SqlParameter paramOutput = new SqlParameter("#Output", SqlDbType.nVarChar);
paramOutput.Direction = ParameterDirection.Output;
Stored procedures can have return values and output parameters in addition to input parameters.
Use an Output Parameter.
Change ParameterDirection.Input to ParameterDirection.Output when defining a param "#Id".
PS. What are you passing right now to the sproc (Id.ToString()) if the id is generated in the DB? Why aren't you just using autoincrement column?

Retrieving output parameter from stored procedure with oledb command vb.net

My stored procedure:
PROCEDURE [dbo].[addMasterTransaksi]
#kodeSuplier varchar(10),
#Total money,
#kodeUser varchar(10),
#isLunas varchar (2),
#Dp money,
#kodeTrans varchar(10) output
AS
BEGIN
Declare #KdTrans as varchar(10);
Declare #Kode as int;
Declare #thisYear as varchar(10);
select #thisyear = RIGHT(YEAR(getDate()),2)
SELECT TOP(1) #KdTrans = SUBSTRING(kodeTransaksi,5,6) FROM TblMasterPembelian WHERE YEAR(Tanggal) = YEAR(getDate()) order by kodeTransaksi desc;
--print #KdTrans
IF #KdTrans IS Null
SET #KdTrans = 'TB'+ #thisYear +'000001'
else
begin
select #Kode = convert(int,#KdTrans);
select #Kode = #Kode + 1;
select #KdTrans = convert(int,#Kode);
select #KdTrans = '00000' + #KdTrans;
select #KdTrans = right(#KdTrans,6)
select #KdTrans ='TB' + #thisYear + #KdTrans
end
SET NOCOUNT ON;
--ke Master Pembelian
INSERT INTO TblMasterPembelian(kodeTransaksi,Tanggal,Total,kodeSuplier,kodeUser,isLunas,DP)
VALUES (#KdTrans,getDate(),#Total,#kodeSuplier,#kodeUser,#isLunas,#Dp)
set #kodeTrans =#KdTrans
--print #kodeTrans
return #kodetrans
END
VB.NET code:
Public Function addMasterPembelianny(ByVal kodesup As String, ByVal total As Long, ByVal kodeUser As String, ByVal isLunas As String, ByVal dp As Long)
Dim kodeTransaksi As String
modKoneksi.bukaKoneksi()
command.Connection = modKoneksi.koneksidb
command.CommandType = CommandType.StoredProcedure
command.CommandText = "addMasterTransaksi"
command.Parameters.Add("#kodeSuplier", OleDbType.VarChar, 10, ParameterDirection.Input).Value = kodesup
command.Parameters.Add("#Total", OleDbType.BigInt, 10, ParameterDirection.Input).Value = total
command.Parameters.Add("#kodeUser", OleDbType.VarChar, 10, ParameterDirection.Input).Value = kodeUser
command.Parameters.Add("#isLunas", OleDbType.VarChar, 2, ParameterDirection.Input).Value = isLunas
command.Parameters.Add("#Dp", OleDbType.BigInt, 10, ParameterDirection.Input).Value = dp
command.Parameters.Add("#kodeTrans", OleDbType.Char, 10)
command.Parameters("#kodeTrans").Direction = ParameterDirection.Output
command.ExecuteReader()
kodeTransaksi = command.Parameters("#kodeTrans").Value
modKoneksi.tutupKoneksi()
Return kodeTransaksi
End Function
I have problem when I want to retrieve parameter from a stored procedure..
When I run that code, there appear an error like this message ..
Conversion failed when converting the varchar value 'TB13000005' to data type int.
Why they said that failed converting to data type int??
What's wrong with my code..?
master help me please..
I believe it is this line in your stored procedure which is causing the error:
return #kodetrans
Stored procedures can only return integers as part of the RETURN statement so the line fails (as #kodetrans is a VARCHAR). You can just remove that line completely...For output parameters, what you have done here:
set #kodeTrans =#KdTrans
In the stored proc is fine and should be sufficient/OK.

execute a stored procedure that returns a " completed succesfully " clue

i have a stored procedure
UPDATE tblTime
SET TimeOut = DATEADD(HOUR,8,TimeIn)
WHERE tId =
(
SELECT MAX(tId)
FROM tblTime
WHERE UserId = 3571
)
although there's no question really, in that case if it did succeed in this query
cause even if the field is empty or if it has value,
it will in this case succeed
but i do need it for future other queries... and also ,
in this case i want the C# code to report
not only that it was requesting query to be execute - meaning it did happen,
but to get an actual answer from sql server
as a return value that c# could use or turn into Boolean
i have managed to do somthing about this so i can specify a condition inside sql server stored proc
declare an OUTPUT variable(PARAMETER) then
set its value to say 1 if condition is met and -1 if not
then
in c# set a function as follows
in this example outpout parameter is named ERROR
public static int UpdateTblViaStoredPRoc(string SPname, int UserID)
{
int message = 0;
using (SqlConnection con = new SqlConnection("server=(local);Initial Catalog=****DBNAME HERE***;Integrated Security=True"))
{
con.Open();
SqlCommand cmd = new SqlCommand(SPname, con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Uid", UserID);
cmd.Parameters.Add("#ERROR", SqlDbType.Int);
cmd.Parameters["#ERROR"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
message =(int) cmd.Parameters["#ERROR"].Value;
con.Close();
}
return message;
}
stored proc is then allways following the same pattern
declare ERROR parameter, set a condition to output the ERROR accordingly :
ALTER PROCEDURE [dbo].[nameofProc]
#UId Int, #ERROR int OUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #TimeOtVal varchar(50)
set #TimeOtVal = (SELECT CASE WHEN [TimeOut] IS NULL THEN '' ELSE CONVERT(NVARCHAR,[TimeOut]) END FROM tblTime WHERE tId = ( SELECT MAX(tId) FROM tblTime WHERE UserId = #UId))
IF (#TimeOtVal = '') -- condition for the update
BEGIN -- now action is taken if condition is met
SET NOCOUNT ON;
UPDATE tblTime SET TimeOut = DATEADD(HOUR,8,TimeIn) WHERE tId = ( SELECT MAX(tId) FROM tblTime WHERE UserId = #UId)
SET #ERROR = 1
END
else
BEGIN -- Other wise , if condition isnot met
SET #ERROR = -1
END
END
so it does what you want only if you allowed it by the condition
then reports the action so you can handle it in program code behind .