In the database I generate a random winning box number and store it. However, I also need to pass @winningBox back to the VB code and store it in Session("winningBox"). I've tried a few different ways but cant figure it. I tried adding:
Dim DR As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
While DR.Read
session("winningBox") = DR("winningBox")
End While
But I'm unsure how or where exactly to add it.
MS SQL
ALTER PROCEDURE [dbo].[addEntrant]
@accountID uniqueidentifier,
@fileID int,
@boxNo int,
@buyPrice int
AS
BEGIN
IF NOT EXISTS (SELECT boxNo FROM tblEntrants WHERE fileID=@fileID AND boxNo=@boxNo)
BEGIN
INSERT INTO tblentrants (accountID, fileID, boxNo, dateAdded) VALUES (@accountID, @fileID, @boxNo, getDate() )
UPDATE tblAccounts SET coins=coins-@buyPrice WHERE accountID=@accountID
IF (SELECT COUNT(*) FROM tblEntrants WHERE fileID=@fileID)=3
BEGIN
UPDATE tblItems SET winner =(SELECT ABS(CHECKSUM(NEWID()) % 3) + 1) WHERE fileID=@fileID
UPDATE tblItems SET sold='c', dateBought=GETDATE() WHERE fileID =@fileID
UPDATE I
SET I.buyersAccountID = E.accountID
FROM tblItems AS I
INNER JOIN tblEntrants AS E ON I.fileID = @fileID
AND I.winner = E.boxNo
DECLARE @winningBox int
SET @winningBox = (SELECT winner from tblItems WHERE fileID=@fileID)
RETURN @winningBox
END
END
END
VB.Net
Dim DBConnect As New DBConn
Using db As DbConnection = DBConnect.Conn("DBConnectionString")
Dim cmd As SqlCommand = DBConnect.Command(db, "addEntrant")
cmd.Parameters.Add(New SqlParameter("accountID", SqlDbType.UniqueIdentifier, ParameterDirection.Input)).Value = acc.accountID
cmd.Parameters.Add(New SqlParameter("fileID", SqlDbType.Int, ParameterDirection.Input)).Value = Request.QueryString("oid")
cmd.Parameters.Add(New SqlParameter("boxNo", SqlDbType.Int, ParameterDirection.Input)).Value = boxNo
cmd.Parameters.Add(New SqlParameter("buyPrice", SqlDbType.Int, ParameterDirection.Input)).Value = CInt(session("buyPrice"))
db.Open()
cmd.ExecuteNonQuery()
cmd.Dispose()
cmd = Nothing
db.Dispose()
db.Close()
End Using
1条答案
按热度按时间nukf8bse1#
Return
in an SQL procedure can work, but it's limited to only integer values. . It really intended for other purposes.Or you could use an
OUTPUT
parameter, as suggested by others. Just remember: the OUTPUT parameters must still be defined at the beginning of the procedure, just like the INPUT parameters.Personally, I find it easiest in most cases to
SELECT
the data so it's included with a result set.So let's change the end of the SQL procedure from
RETURN @winningBox
toSELECT @winningBox
. Now you can update the VB.Net like this:Note the extra setting
cmd
toNothing
at the end of a method harks back to the old VB6 era. This was important back then, but is no longer ever in any way helpful for .Net, and in some rare cases can be actively harmful. You should not set variables to Nothing at the end of a method or scope block anymore; let the garbage collector do it's job in the normal way. In this case, theUsing
block means you don't even need any of theClose()
orDispose()
calls.But I'm concerned this still won't fix the issue. The
RETURN
/SELECT
is nested two levels deep inIF
blocks, so there's no guarantee the line will ever run. You may want to have some kind of fall-back to better account for the possibility no box is selected.I'm also concerned this is moving "coins" around in multiple steps separate from any transaction. This code cries out for a TRANSACTION with a TRY/CATCH where the last line of the TRY block does a COMMIT and the CATCH block does a ROLLBACK.