Something is wrong with the code or the stored procedure - vb.net

To start I'll tell you this. The next question is tricky for me, but... This Stored procedures is used in two different databases. Both have the same data, let's call them older and newer.
In the older the stored procedure works fine and I even get the return. But in the Newer doesn't happen the same.
ALTER PROCEDURE dbo.actual_user
#user char(15)
AS
SELECT
US.Usercode, US.UsercodeSQL, US.LastName, US.Name, US.Nivel,
CONVERT(int, US.Timestamp) TS,
S.DateChanged, S.TolPSW, S.LoginsTotals, S.LoginsUsed,
S.InitialDate, S.EndDate
FROM
System_Users US
INNER JOIN
Session_Users S ON US.UssercodeSQL = S.UssercodeSQL
WHERE
US.UsercodeSQL = user_id(#usuario)
AND S.UsercodeSQL = user_id(#usuario)
When I run an EXEC like this (by this way works in both databases):
exec actual_user 'telc\u124453'
I get this output:
Usercode UsercodeSQL LastName Name Nivel TS DateChanged TolPSW LoginsTotals LoginsUsed InitialDate EndDate
----------------------------- ----------- ------------------------------ ------------------------------ ------ ----------- ----------------------- --------------- ------------- ------------ ----------------------- -----------------------
FESPE 15 Brond Manny NULL 16838419 2007-04-16 16:57:00 30 10 0 NULL NULL
But the code I'm using doesn't work in the newer database. It's just like this.
Here is my new code. It works in the older DB but in the newer doesn't. May the version of SqlServer is not working cause of user_id from the Stored Procedure, I don't know.
Public Function UsuarioActual(ByVal datoUsuario As String) As DSUsuario.UsuarioActualRow
Dim ds As New DSUsuario
Dim dt As New DataTable
Dim sqlConn As SqlConnection = New SqlConnection()
Dim sqlAdp As SqlDataAdapter
Try
sqlConn = MyBase.GetConnection
Dim command As New SqlCommand("Usuario_Actual", sqlConn)
command.CommandType = CommandType.StoredProcedure
command.Parameters.AddWithValue("#usuario", datoUsuario)
sqlAdp = New SqlDataAdapter(command)
sqlAdp.Fill(dt)
Catch ex As Exception
proc = "UsuarioActual"
ERROR
epn = New FactEspExceptions(ex, TipoExcepcion.ErrorBD, proc, Nothing, ex.Message)
epn = New FactEspExceptions(ex, TipoExcepcion.ErrorBD, proc)
epn.AuditarError()
Throw epn
Finally
sqlConn.Close()
sqlConn = Nothing
End Try
If ds.UsuarioActual.Rows.Count > 0 Then
Return ds.UsuarioActual.Rows(0)
Else
Return Nothing
End If
End Function`
Edit 1:
When the code runs, on the Older DB it works. But when it runs on the Newer DB, it doesn't. I don't know if it's about permissions, execSP, or something is missing. So in my point of view, i can say the problem is on the SP.
Edit 2:
Running from the code I get no output.
This is the error running from an EXEC on both DB.
Procedure 'actual_user' has no parameters and arguments were supplied
Edit 3: Code updated.

Dim comando As String = "EXEC actual_user"
Try
sqlConn = MyBase.GetConnection
Dim com As SqlCommand = New SqlCommand()
com.CommandText = comando
com.Connection = sqlConn
com.CommandType = CommandType.StoredProcedure
com.Parameters.AddWithValue("#User", usuTelecom)
The reason you're getting the error is that no parameters are being passed. This will pass the parameter in question.
The one thing I don't understand in your stored procedure is why there's a #usuario variable that doesn't seem to be declared. I'm thinking that you stripped some stuff out, though.

Related

How do I retrieve a value from an SQL query and store it in a variable in VB.NET?

I am trying to find the max product ID and store the value in a local variable "MaxID" and return this value. I am trying to convert the result of the query into an Integer type but I am not able to do it. Below is the code:
Public Function GetMaxID(ByVal TableName As String, ByVal ID As String) As Integer
Dim MaxID As Integer
Dim sqlquery As SqlCommand
Dim field_name As String = ID
Dim con As SqlConnection
con = New SqlConnection()
con.ConnectionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename='D:\Docs Dump\Work\Srinath\SrinathDB.mdf';Integrated Security=True;Connect Timeout=30"
con.Open()
Try
sqlquery = New SqlCommand("SELECT MAX( #field ) FROM #table ", con)
sqlquery.Parameters.AddWithValue("#field", field_name)
sqlquery.Parameters.AddWithValue("#table", TableName)
MaxID = CInt(sqlquery.ToString)
con.Close()
Return MaxID
Catch ex As Exception
Return 0
Exit Function
con.Close()
End Try
End Function
End Class
MaxID = CInt(sqlquery.ExecuteScalar())
You also should know about SqlCommand.ExecuteReader(), SqlCommand.ExecuteNonQuery() (for inserts/updates/deletes), and SqlDataAdapter.Fill().
Where you'll still have a problem is you can't use a parameter value for the table name or column name. The Sql Server engine has a "compile" step, where it has to be able to work out an execution plan, including permissions/security, at the beginning of the query, but variable names like #table and #field aren't resolved until later. It's not what actually happens, but think of it as if you had string literals in those places; imagine trying to run this:
SELECT MAX('ID') FROM 'MyTable'
MAX('ID') will always return the string value ID, and not anything from an ID column in any rows. But the MyTable part is not the correct place for a string literal, and such a query wouldn't even compile.
I also see people here from time to time try to create functions like GetMaxId(), and it's almost always misguided in the first place. If the intended use for this function is the same as what I usually see, you're setting up a major race condition issue in your application (one that probably won't show up in any testing, too). Sql Server gives you features like identity columns, sequences, and the scope_identity() function. You should be using those in such a way that new IDs are resolved on the server as they are created, and only (and immediately) then returned to your application code.
But that issue aside, here's a better way to structure this function:
Public Class DB
Private conString As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename='D:\Docs Dump\Work\Srinath\SrinathDB.mdf';Integrated Security=True;Connect Timeout=30"
'You want a separate method per-table that already knows the table and column names
Public Function GetMyTableMaxID() As Integer
Dim sql As String = "SELECT MAX(ID) FROM MyTable"
Using con As New SqlConnection(conString), _
sqlQuery As New SqlCommand(sql, con)
'Parameters would go here.
'Do NOT use AddWithValue()! It creates performance issues.
' Instead, use an Add() overload where you provide specific type information.
'No exception handling at this level. The UI or business layers are more equipped to deal with them
con.Open()
Return CInt(sqlQuery.ExecuteScalar())
End Using
'No need to call con.Close()
'It was completely missed in the old code, but handled by the Using block here
End Function
End Class

Checking a database for specific dates to prevent a booking cross over

I have an ASPX web form where a logged-in user will be able to choose from a number of suit jacket sizes already stored in a database table. Once chosen the jacket size along with a from and to date for a booking the data is entered into a booking table with the relevant information.
I need help with code that will ensure that when another user chooses a suit jacket size they cannot use the same dates that are stored in the booking table for that size. The output would be in a label with an error message telling the user that the jacket size is unavailable for these dates.
I am using ASP.NET and the language VB for all of this work.
Any help would be appreciated!
This can be done with an If...Then statement check and a SQL query for the lookup.
Dim mySqlConnection As New SqlConnection("Your connection string")
Dim cmd As New SqlCommand
Dim reader As SqlDataReader
cmd.CommandText = "SELECT [ID] FROM [Table] WHERE (JacketSize = #jacketSize AND (DateFrom <= #dateWanted AND DateTo >= #dateWanted))"
cmd.CommandType = CommandType.Text
cmd.Connection = mySqlConnection
cmd.Parameters.Add("#jacketSize", 'JacketSize field')
cmd.Parameters.Add("#dateWanted", 'DateWanted field')
mySqlConnection.Open()
reader = cmd.ExecuteReader()
If (reader.HasRows = TRUE) Then
'code to execute if date is taken'
Else
'code to execute if date is not taken'
End If
mySqlConnection.Close()
Edit: Forgot to add the parameters. Thanks Andrew Morton.

VB .NET Paramaterized SQL call not correctly parsing IN clause arguments [duplicate]

This question already has answers here:
Parameterize an SQL IN clause
(41 answers)
Closed 6 years ago.
So I am currently working on a project where I am looking to retrieve all data from a table matching a modifyable list on the screen. Here is a sample of the code that I am using to make the call
Public Sub GetAnimals(ByReg selectedTypes As String)
Dim strSql As String
Dim pselectedTypes As SqlClient.SqlParameter = New SqlClient.SqlParameter("#pselectedTypes", selectedTypes)
Dim strDBConnection As String = DBConnection.GetConnection.ConnectionString
Dim rs As DataSet = new DataSet
strSql = "SELECT * FROM PetInformation WHERE AnimalType IN (#pselectedTypes)"
Using sqlConn As SqlClient.SqlConnection = New SqlClient.SqlConnection(strDBConnection)
sqlConn.Open()
Using sqlcmd As SqlClient.SqlCommand = New SqlClient.SqlCommand
With sqlcmd
.Connection = sqlConn
.CommandTimeout = DBConnection.DLLTimeout
.CommandType = CommandType.Text
.CommandText = strSql
.Parameters.Add(pselectedTypes)
Using sqlda As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter(sqlcmd)
sqlda.Fill(rs)
End Using
End with
End Using
End Using
' Data Calculations
End Sub
This then makes the SQL query look something like this. For this example I'm using my list of animals as just cats and dogs.
exec sp_executesql N'SELECT * FROM PetInformation WHERE AnimalType IN (#pselectedTypes)',N'#pselectedTypes nvarchar(22),#pselectedTypes='''cat'',''dog'''
So everything looks all fine and dandy but when I go to run it and execute it I don't get any results back. If I change the sql to look like either one of these I get data back, but since this SQL is generated that's not really an option w/o switching away from parameterized sql, which I don't want to do.
exec sp_executesql N'SELECT * FROM PetInformation WHERE AnimalType IN (''cat'',''dog'')',N'#pselectedTypes nvarchar(22),#pselectedTypes='''cat'',''dog'''
or
SELECT * FROM PetInformation WHERE AnimalType IN ('cat','dog')
Any suggestions or ideas?
As far as I know, no db libraries allow parameterizing lists like you are trying. In those situations, you need to build your parameter list and query dynamically based on the number of elements in your list.

Select Statement SQL in VB

I understand that there are other posts such as this, however I cannot find one that will work for me and Im really at the end of my tether with this, I really dont know what to do.
I have a few tables with ID columns and name columns, that are connected by Link Tables through foreign keys etc. I'm trying to enter data into the database via a GUI and to do so I'm using insert statements into the 'regular' tables, then Select statements to get the autogen IDs from the regular table to then insert into the link tables.
The code below is what I've been trying to use to do this.
Imports System.Data.SqlClient
Public Class Test
Private cs As New SqlConnection(".....")
Private Sub btnInsertNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInsertNext.Click
Dim ContID As Integer
Dim FName As Integer
cs.Open()
Using command As New SqlCommand("Select FamID From Family Where Name = '" & FName & " '", cs)
command.Parameters.AddWithValue("#FamID", ContID)
command.ExecuteNonQuery()
End Using
Using command As New SqlCommand("Select DocID From Doctors Where DocName LIKE'" & AddFam.Doctor & " '", cs)
command.Parameters.AddWithValue("#DocID", AddFam.Doctor) ''AddFam is another form I'm using to add a family member to a Doctor
command.ExecuteNonQuery()
End Using
cs.close()
I'm using:
VB 2010
SQL server management 2008 r2
I understand its a bit muddley but any help would be greatly appreciated, and I'm sorry if this has come up before.
It's not really clear what problem you actually have, i assume that you don't know how to retrieve newly generated IDs.
Here is an self-explanatory example on how to retrieve new identity values with ADO.NET:
Using con = New SqlConnection(connectionString)
Dim newID As Int32
Using insertCommand = New SqlCommand("INSERT INTO Test(Value)VALUES(#Value);SELECT CAST(scope_identity() AS int)", con)
insertCommand.Parameters.AddWithValue("#Value", "Value1")
con.Open()
newID = DirectCast(insertCommand.ExecuteScalar, Int32)
End Using
If newID <> 0 Then
Using updateCommand = New SqlCommand("UPDATE TEST SET Value='Value1.1' WHERE idTest=#idTest", con)
updateCommand.Parameters.AddWithValue("#idTest", newID)
If con.State <> ConnectionState.Open Then con.Open()
Dim updatedRecordCount = updateCommand.ExecuteNonQuery
End Using
End If
End Using
The 2 important parts are:
SELECT CAST(scope_identity() AS int)
which will return the new identity value
DirectCast(insertCommand.ExecuteScalar, Int32)
which will return the new Identity column value if a new row was inserted, 0 on failure.
Since you're mixing using parameters with string-concatenation: using parameters is very important because it will prevent SQL-Injection.
SCOPE_IDENITY
ExceuteScalar-Method
Commands and Parameters in ADO.NET
NO! Parameterise your queries like this.
command = New SqlCommand("Select FamID From Family Where Name = #Fname", cs)
command.Parameters.AddWithValue("#Fname", ContID)
FamID = command.ExecuteScalar()
And ideally, you should use Scope_Identity() to get the Identity from you insert statement
You can try with this code on two queries based on # symbol
...
Using command As New SqlCommand("Select FamID From Family Where Name = #FamID", cs)
command.Parameters.AddWithValue("#FamID", ContID)
...
Using command As New SqlCommand("Select DocID From Doctors Where DocName LIKE #DocID", cs)
command.Parameters.AddWithValue("#DocID", AddFam.Doctor)
...

Executing stored procedure in vb.net

I need to execute a stored function in oracle or sql through vb.net.
I created a command object. Depending on the database type(oracle or SQL) i am preparing the
Command text as Select functionName(?,?,?,?,?,?,?,?) from dual; (For Oracle)
Adding the parameter values of the function
Now performing the ExecuteScalar which is not working saying invalid parameter.
This works with ODBC connection string. But ODBC doesn't with 64bit.
My Requirement: Code should execute a user defined stored procedure by taking the values at runtime.
Thanks
Rupesh
Your command text should be just the Stored procedure name without a select, and make sure you set the command type to stored procedure. Check out this link for example:
http://support.microsoft.com/kb/321718
Oracle:
Dim cmd As New OracleCommand
cmd.Connection = conn
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "OracleSP"
Dim p1 As OracleParameter
Dim p2 As OracleParameter
p1 = cmd.Parameters.Add("Param1", OracleType.NVarChar)
p1.Value = "Value1"
p2 = cmd.Parameters.Add("Param2", OracleType.Double)
p2.Value = 10
cmd.ExecuteNonQuery()
SQL Server:
cmd.Connection = conn
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "SqlSP"
cmd.Parameters.Add("#Param1", SqlDbType.Int)
cmd.ExecuteNonQuery()
I am not sure about Oracle as I haven't done it (I think it should work) but with Sql server you can use:
SqlCommandBuilder.DeriveParameters(cmd)
to populate the SqlParametersCollection on the command, instead of setting them like I did.
MSDN documentation
After that you can loop thru them and set your values as necessary.