I have a problem, I'm working on a school project with Visual Basic and I can't manage to fill a dataset with a LIKE query.
I'm using Access in order to manage the database and the query is:
SELECT * FROM VistaProductos WHERE Nombre LIKE "*ta*"
In Access this query is working fine but when I use it on Visual Basic the OleDbDataAdapter fills my DataSet with 0 rows.
Here is the code:
Dim adaptador As New OleDbDataAdapter("SELECT * FROM VistaProductos WHERE " & campo & " LIKE ""*" & valor & "*""", conexion)
adaptador.Fill(dataset, tabla)
Return dataset
campo and valor are variables who have the same data as in the Access example, and I tried by writing them literally too.
The connection to the database is working fine as the other querys work perfectly.
ADO.NET uses the standard % character as wildcard in LIKE expressions.
But your first problem to solve is removing the string concatenations when you build sql queries. You cannot trust your user on this point. If you leave in that way you user can write anything and you risk to pass malicious commands to your database engine. You should always use parameters in these contexts
In your code is present also a field name as a variable part of the query.
This cannot be parameterized, so the only sensible solution is to present your user with a list of field names to choose from
Dim cmdText = "SELECT * FROM VistaProductos WHERE " & campo & " LIKE #valor"
Dim adaptador As New OleDbDataAdapter(cmdText, conexion)
adaptador.SelectCommand.Parameters.Add("#valor", OleDbType.VarWChar).Value = "%" & valor & "%"
adaptador.Fill(dataset, tabla)
Return dataset
Related
I would like to know if there is a way to get system username and use it directly in an MS Access query. I have made a parameter work within a query from a combo box on a form and I have also acquired system name in Access VBA using ENVIRON ("USERNAME").
Kindly let me know if this is possible.
You need to create a VBA function that returns the username, and then use the function in the query.
Public Function GetUserName() As String
' GetUserName = Environ("USERNAME")
' Better method, see comment by HansUp
GetUserName = CreateObject("WScript.Network").UserName
End Function
and
SELECT foo FROM bar WHERE myUserName = GetUserName();
My solution kept all the work in VB.
I used a variable for the windows login username and then created a SQL string with that variable inserted. Lastly, I updated the query behind the form to use this new SQL string.
The CHR(34) puts quotes around the name as it is now a string inside the SQLSTR and needs to be within a set of quotes.
If you have a complex SQL statement, write it in the QBE using a string for the name and all the other variables, then switch to the SQL view and replace it using a VBA variable as shown below.
MyName = Environ("username")
sqlstr = "SELECT * From Projects WHERE ( ((Projects.LeadEngineer)=" & Chr(34) & MyName & Chr(34) & " AND ActiveYN = True ));"
Forms![Main Form].RecordSource = sqlstr
You can use SYSTEM_USER if the query is being executed in a SQL Server, that will retrieve the user name connected to the database (for that, make sure you are not using fixed user name in your connection string)
Yes - you can use the 'CurrentUser' function in your query. Here I've included it as a field and criteria.
SELECT Field1, Field2, [CurrentUser] AS UserName FROM Table1 WHERE Field1 = [CurrentUser];
Background: a LOB app we use has the ability to use macros written in VBScript, but no access to WScript, etc., as far as I know.
I have successfully received user input, passed it to a stored procedure on a SQL Server, and returned a recordset to the VBScript macro in the application.
What I want to do now, is write a function or loop or something, that for as long as there is a record left in the recordset, accept additional user input, and check this against the returned recordset.
The recordset returned from SQL Server contains two columns: PART_ID and PART_QTY. For as many number of entries there are, I want to accept additional user input, lets say PART_ID_INPUT and PART_QTY_INPUT, and validate it against the in-memory recordset.
My biggest problem is working with the disconnected recordset.
When in doubt, read the documentation. You can use the Filter and RecordCount properties to determine if the recordset contains matching records:
part_id_input = InputBox("Enter part ID:")
If part_id_input <> "" Then
rs.Filter = "PART_ID = '" & part_id_input & "'"
If rs.RecordCount > 0 Then WScript.Echo "Found matching record."
End If
The filter is cleared by setting it to an empty string:
rs.Filter = ""
The current record can be removed from the recordset using the Delete method:
rs.Delete
Navigate through records via MoveFirst/MoveLast/MoveNext/MovePrevious.
I'm trying to implement the change password module in a application in VB. The update query is having some issues
Private Sub cmdOK_Click()
Query = "Select * From Users Where LoginID='" & txtLoginID & "' and Password = '" & txtCuPassword & "'"
Set reSet = myCon.Execute(Query)
If (Not reSet.BOF) And (Not reSet.EOF) Then
Query1 = "UPDATE Users SET Password ='" & txtNewPassword & "' WHERE LoginID='" & txtLoginID & "'"
Set reSet = myCon.Execute(Query1)
When executed an error is thrown at UPDATE query, as syntax error.
So, if your code has a single quote in the txtNewPassword field, your query ends up something like this
Query = "UPDATE Users SET Password ='mypass'word' WHERE LoginID='123'"
and this, of course is a syntax error.
You could try to replace a single quote with a pair of single quotes
Query = "UPDATE Users SET [Password] ='" & Replace(txtNewPassword, "'", "''") & "' WHERE ....
But remember that this code is open wide to SQL Injection. You should use parametrized queries also if it is not really easy to do that in VB6. Also, as pointed out by HansUp in its comment, you need to enclose the reserved word Password with square brackets
Why should I use Parameters instead of putting values into my SQL string
i have an VBA code where i am calling oracle to retrieve data twice using ODBC.
First data retrieval is fine. But 2nd time it is saying ,
**RunTime Error '-2147467259 (80004005)'; Unspecified error**
My Code is as follows,
Note: Same code works for connecting Teradata but failed when i use
Oracle
'First Data retrieval
Query1 = "Select TableName from all_tables"
CmdSQLData.CommandText = Query1
CmdSQLData.CommandType = adcmdText
CmdSQLData.Timeout=0
set rs = CmdSQLData.Execute()
'Then code to store data ...
'This part gives proper result ...
rs.close()
'Second Data retrieval
Query2 = "Select * from db.Event"
CmdSQLData.CommandText = Query2
CmdSQLData.CommandType = adcmdText
CmdSQLData.Timeout=0
set rs = CmdSQLData.Execute() 'This line Gives Error - RunTime Error '-2147467259 (80004005)'; Unspecified error
Also i tried creating new command object as cmdSQLData1 but still same
error
May i know why the error is coming for second query ?
There is no problem with query as i have tested in oracle directory.
Please let me know
You won't see this documented much of anywhere, but reusing Command objects with different comamndText is actually a bad practice. You don't say what kind of connection you're using, but for example if it's ODBC, this will internally send a fake invalid SQL to Oracle to force a cleanup of some kind. So instead, throw away your Command object after use and create a new one.
Reusing Command objects is a good practice when you're re-executing the same query with different parameter values, but that's not the case here.
You do not need to use command text at all for those types of queries what you could do is :-
` Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
con.Open "DSN=Oracle", "User", "Password"
rs.Open "select * from table_a", con
' Read all results
rs.Close
rs.Open "select * from table_b", con
' Read all results
rs.Close
con.Close
You only need to use "Command" if you plan to use a store procedure or a query with bound parameters.
How can I use Linq with Dataset.xsd files?
I've looked at Linq-to-Datasets and Linq-to-XSD but they don't really seem to work directly with the Visual Studio DataSet.xsd files.
EDIT: I actually found a great link for this: link text but I can't seem to figure out what to do if I want to query on related tables.
Dim taFields As New TestDSTableAdapters.FieldTableAdapter()
Dim fields = taFields.GetData()
Dim results = From f In fields Select f
For Each field In results
Response.Write(field.FieldID & " " & field.Label & " " & field.FieldTypeRow.FieldTypeLabel)
Next
I get an "Object reference not set to an instance of an object." error when running the above code because, I guess, field.FieldTypeRow.FieldTypeLabel isn't actually part of the query of data. Do I have to create a method that returns data from that data also? I'm assuming this would be the case (that taFields.GetData has to return all the FieldType data results too if I'm going to reference it - in Linq to SQL it does all this for me so it's a little disappointing)
A DataSet is just a container for your data, so you need to fill it first. LINQ to SQL will create SQL and go to the database for you...but when you're working with DataSets, you're using LINQ to Objects, which won't create SQL. So you need to make sure that all tables you need in the DataSet are filled before you start writing LINQ to query your DataSet.
I think you're looking for something along these lines:
Dim taFields As New TestDSTableAdapters.FieldTableAdapter()
Dim taFieldTypes As New TestDSTableAdapters.FieldTypesTableAdapter()
Dim ds As New TestDS
taFields.Fill(ds.Fields)
taFieldTypes.Fill(ds.FieldTypes)
Dim results = From f In ds.Fields Select f
For Each field In results
Response.Write( _
field.FieldID & " " & field.Label & " " &
field.FieldTypeRow.FieldTypeLabel)
Next
Dim taFields As New TestDSTableAdapters.FieldTableAdapter()
Dim fields as TestDSTableAdapters.FieldsDataTable = taFields.GetData()
Dim results = From f In fields Select f
For Each field In results
Response.Write(field.FieldID & " " & field.Label & " " & field.FieldTypeRow.FieldTypeLabel)
Next
You forgot to set the type for fields. That is why yo uwere getting object reference problems. You do not have to create a new blank dataset.