vb.net trim word from end of string - sql

I am trying to run an SQL query in my vb.net application using a loop
SQL = "SELECT * FROM table WHERE "
For m = 1 To num_array
SQL = SQL & "type = '" & array(m, 1) & "' OR "
Next
but its showing an OR at the end.
how can i trim this last OR from my query?

This seems a job for a StringBuilder
Dim sql = new StringBuilder("SELECT * FROM table WHERE ")
For m = 1 To num_array
sql.Append("type = '" & array(m, 1) & "' OR ")
Next
If num_array > 0 Then
sql.Length -= 4
End If
However you should pay special care to your string concatenation. It seems that your array doesn't contain numbers but string because you are putting everything between single quotes and this means that your type field is a string not a number.
Of course I hope that your array content is not directly inserted by your user otherwise you have a big security risk called Sql Injection. Anyway look at how to build a parameterized query.
Something like this
Dim prms = New List(Of SqlParameter)()
Dim num_Array = 4
Dim sql = New StringBuilder("SELECT * FROM table WHERE ")
For m = 1 To num_array
sql.Append("type = #p" & m & " OR ")
prms.Add(New SqlParameter("#p" & m, array(m, 1)))
Next
If num_array > 0 Then
sql.Length -= 4
End If
Dim cmd = new SqlCommand(sql.ToString(), connection)
cmd.Parameters.AddRange(prms.ToArray())

Related

Using ADODB recordset doesn't return a value when same query in Access does

I am having a frustrating problem with EXCEL VBA using an ADODB recordset. I have a query which directly in Access works correctly but when I put it in the VBA the recordset always comes back null. I have other queries that work as expected but something about this type of query always fails to return a result in VBA even though it works in Access.
Below is the function responsible for executing the query. It is built to allow me to do counts, and in a similar function, sums on the ProjList table. The first style query is used where no year limiting flag is to be used (sYrIn = -1) and it works as expected.
The second style query is when the year in flag contains a value to limit the count or sum to a specific year. Our Project IDs are of the form X99-999 where the first position denotes a type of project, the next two digits signify the year the project opened and the last three digits are a unique incremented number which resets to 001 each year.
There are a number of lines here that are only for debugging feedback. Below the code I have included some of the debugging output.
I understand we are to ask a specific question, but I have four that are tightly related to this situation and code sample and do not think that four posts so tightly related are a good thing. My questions are about the second set of queries. They never work in VBA.
1) Am I reading the recordset incorrectly in that case?
2) Is there some limitation to the "complexity" of query that can be executed in this way?
3) Why does the first query return runs and the second doesn't?
4) Is there a better way to see the real query execution result?
Again all of the queries work in Access.
Note: the code as it appears has the year search hard coded since the actual code uses the current year and not enough data for 2020 exists for the result to be meaningful (0 is 0!)
Also there are two queries for the second type. One is commented out--it suffers the same failure in VBA and success in Access.
Function GetDBProjCount(sCharIn As String, sFldIn As String, Optional sYrIn As Integer = -1) As Integer
Dim iResult As Integer
Dim sQryString As String
Dim sSearchChar As String
Dim pQryParam As Object
Dim sParamValA As String
Dim sParamValB As String
Dim iParamLenA As Integer
Dim iParamLenB As Integer
iResult = 0
Call MakeDBConnection
Set pQryParam = CreateObject("ADODB.Parameter")
If CInt(sYrIn) > 0 Then
If ((CInt(sYrIn) > 10) And (CInt(sYrIn) < 50)) Then
sYrIn = Right(sYrIn, 2)
ElseIf ((CInt(sYrIn) > 2010) And (CInt(sYrIn) < 2050)) Then
sYrIn = Right(sYrIn, 2)
Else
sYrIn = -1
End If
End If
If sYrIn < 0 Then
sQryString = "SELECT Count(*) FROM " & tblProjList & " WHERE Left(" & sFldIn & ", 1)=?;"
sParamValA = sCharIn
sParamValB = ""
iParamLenA = 1
iParamLenB = 1
Else
sQryString = "SELECT Count(*) FROM (Select * from [" & tblProjList & "] WHERE [" & garProjListFlds(4, 1) & "] Like ?) WHERE Left([" & sFldIn & "],1)=?;"
'sQryString = "SELECT Count(*) FROM [" & tblProjList & "] WHERE ((Left([" & sFldIn & "], 1)= ? ) AND ([" & garProjListFlds(4, 1) & "] LIKE ?));"
sParamValA = "*19-*" 'comment "'*" & CStr(sYrIn) & "-*'"
sParamValB = sCharIn
iParamLenA = 8
iParamLenB = 1
End If
If QDebugMode Then Debug.Print "GetDBProjCountA: " & sQryString
With goDBCmd
.ActiveConnection = goDBConn
.CommandText = sQryString
.CommandType = adCmdText
Set pQryParam = .CreateParameter("ParamA", adChar, , iParamLenA, sParamValA)
.Parameters.append pQryParam
If sYrIn > 0 Then
Set pQryParam = .CreateParameter("ParamB", adChar, , iParamLenB, sParamValB)
.Parameters.append pQryParam
End If
Set goDBRecSet = .Execute
End With
If QDebugMode Then Debug.Print ("GetDBProjCountB: Parameters: A: " & sParamValA & " B: " & sParamValB)
Dim msg, fld
For Each fld In goDBRecSet.Fields
msg = msg & fld.Value & "|"
Next
If QDebugMode Then Debug.Print ("GetDBProjCountC: Result: " & msg)
GetDBProjCount = goDBRecSet.Fields(0)
Call CloseDBConnection
End Function
Here is what I see in the immediate window:
GetDBProjCountA: SELECT Count(*) FROM ProjList WHERE Left(ProjArchiveFlag, 1)=?;
GetDBProjCountB: Parameters: A: O B:
GetDBProjCountC: Result: 45|
GetDBProjCountA: SELECT Count(*) FROM (Select * from [ProjList] WHERE [ProjCCID] Like ?) WHERE Left([ProjArchiveFlag],1)=?;
GetDBProjCountB: Parameters: A: *19-* B: O
GetDBProjCountC: Result: 0| (In Access this one returns 44)
The recordset is instantiated in the MakeDBConection sub as
Set goDBRecSet = New ADODB.Recordset
goDBRecSet.ActiveConnection = goDBConn
goDBRecSet.CursorLocation = adUseClient
goDBRecSet.CursorType = adOpenStatic
goDBRecSet.LockType = adLockPessimistic
Set goDBCmd = New ADODB.Command
The connection string is: "Provider=Microsoft.ACE.OLEDB.12.0;" & " Data Source=" & DBPath
Try using wildcard character % not asterik *

Trouble building an SQL Query from VB.NET checklistbox options

I am trying to create an sql query from options selected in a checkListBox. The user will select all of the modules they want (in the checklistbox) to include data from, it will then build the query to collect this data. They will also enter a range for a rating value that will be included in the query. I am very new to using sql so I am struggling to understand what operator is missing from the final query.
This is what I have at the moment:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim h As Integer
Dim queryString As String
Dim moduleArray(6) As String
Dim counter As Integer = 0
Dim provider As String
Dim database As String
Dim connString As String
Dim moduleLen As Integer = 0
Dim moduleString As String = ""
Dim sqlquery As New OleDb.OleDbCommand
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
Change the following to your access database location
database = "C:\Users\mello_000\OneDrive\Google Drive\Computing\Exampapergenerator\users.accdb"
connString = provider & database
Dim myConnection As OleDbConnection = New OleDbConnection(connString)
myConnection.Open()
sqlquery.Connection = myConnection
For h = 0 To h = 6
For Each item As String In Me.CheckedListBox1.CheckedItems
moduleArray(moduleLen) = item
If moduleArray(moduleLen) = "" Then
Else
moduleLen = moduleLen + 1
End If
Next
Next
For i = 0 To moduleLen
If i = 0 Then
moduleString = "'" & moduleArray(i) & "'"
ElseIf i > 0 Then
moduleString = moduleString & "'OR'" + "'" & moduleArray(i) & "'"
End If
Next
queryString = ("SELECT QText FROM Question WHERE QModule = '" & moduleString & "' AND QRating BETWEEN '" & TextBox1.Text() & "'AND'" & TextBox2.Text())
sqlquery.CommandText = queryString
sqlquery.ExecuteNonQuery()
End Sub
However I am getting the output to be: "SELECT QText FROM Question WHERE QModule = ''C1''OR''C2'' AND QRating BETWEEN '1'AND'2"
and an error:
Syntax error (missing operator) in query expression 'QModule = ''C1''OR''C2'' AND QRating BETWEEN '1'AND'2'.
Also, what would be the best way of outputting all of the returned data in a numbered list, in a form that would be printable?
Why are you doing this For h = 0 To h = 6 instead of just For h = 0 To 6?
You don't need single quotes around "'OR'" just use " OR ".
And your SQL syntax is wrong. This QModule = ''C1''OR''C2'' either needs to be QModule = 'C1' OR QModule = 'C2' or a better way QModule IN ('C1','C2')
Assuming QRating is numeric, you don't need single quotes. This QRating BETWEEN '1'AND'2' should be QRating BETWEEN 1 AND 2.
Also you should look into using SQL parameters so you don't have to worry about quotes or escaping them if you have quotes in your data.

Use DataAdapter results as String for new Query

I am in the process of creating a "Related Items" feature for an online store. I have a SQL query that will pull a list of ITEMs from a Database and display them on the page but I'm trying to rig up system where the list will change depending on a few variables.
The code is below and the part I'm having trouble with is getting a usable string out of Query1 to be used as the 'results' variale in query 2.
Public Shared Function GetExtraProducts(ByVal strAddOnCat As String) As DataSet
Dim connect As New SqlConnection
Dim Data1 As New DataSet
Dim data2 As New DataSet
connect.ConnectionString = "SERVER = SERVER-SQL01; Trusted_Connection=yes; DATABASE=GlobalPCSQL"
connect.Open()
Dim query1 As String = ""
Dim query2 As String = ""
query1 = "SELECT StockID FROM dbo.ADDONLISTS WHERE SubCategory = 'Acer-Desktops'"
Dim command1 = New SqlDataAdapter(query1, connect)
command1.Fill(Data1)
If Data1.Tables(0).Rows.Count > 0 Then
query1 = "SELECT StockID FROM dbo.ADDONLISTS WHERE SubCategory = 'Generic'"
Dim command3 = New SqlDataAdapter(query1, connect)
command3.Fill(Data1, "StockID")
End If
Dim results As String = ""
For Each row In Data1.Tables(0).Rows
results += row.ToString() + "','"
Next
If results.Length > 2 Then
results = results.Substring(0, results.Length - 2)
End If
'results = "'HD12047' , 'TV12008'"
query2 = "SELECT stock_items.Stockcode, STOCK_GROUPS.XW_URL as stockgroup, STOCK_GROUP2S.XW_URL as stockgroup2, STOCK_MAINGROUP.XW_URL as stockmaingroup, stock_items.Stockcode as pID, stock_items.description as pName, stock_web.sales_html as pdescription, stock_web.picture_url as pImage, stock_web.picture_url as pLargeimage, stock_items.sellprice1 as pPrice, stock_items.SELLPRICE1, stock_items.SELLPRICE2, stock_items.SELLPRICE3, stock_items.SELLPRICE4, stock_items.SELLPRICE5, stock_items.SELLPRICE6, stock_items.SELLPRICE7, stock_items.SELLPRICE8, stock_items.SELLPRICE9, stock_items.status as itemtype, stock_items.SELLPRICE10 as pListPrice, stock_items.x_totalstock as pInStock, stock_items.x_webhits as pHits, stock_items.ISACTIVE, stock_items.WEB_SHOW, stock_items.X_WebBlub as X_WebBlurb, stock_items.x_webpromo as X_PROMOPAGE, stock_items.last_updated as lastupdated, stock_items.x_stockleveloverride, isnull(stock_items.Restricted_item,'N') as Restricted_item "
query2 += "FROM stock_items Left OUTER Join STOCK_WEB ON (stock_items.Stockcode = STOCK_WEB.Stockcode) LEFT OUTER JOIN STOCK_GROUPS ON (STOCK_GROUPS.GROUPNO = STOCK_ITEMS.STOCKGROUP) LEFT OUTER JOIN STOCK_GROUP2S ON (STOCK_GROUP2S.GROUPNO = STOCK_ITEMS.STOCKGROUP2) LEFT OUTER JOIN STOCK_MAINGROUP ON (STOCK_MAINGROUP.GROUPNO = STOCK_GROUPS.XW_MAINGROUP)"
query2 += "WHERE stock_items.ISACTIVE='Y' AND stock_web.picture_url IS NOT NULL "
query2 += "AND stock_items.Stockcode IN ('" + results + "')"
query2 += results
Dim command2 = New SqlDataAdapter(query2, connect)
command2.Fill(data2)
connect.Close()
Return data2
End Function
Everything works fine if I spoon feed the stock Id numbers into query 2 (in place of the ' + results + ' section, but when I try to use the string from query one all I get is
Incorrect syntax near 'System.Data.DataRow'
Which makes me think that even if I got the syntax sorted, it'l only search for System.Data.Datarow instead of the actual value of the field.
Any help would be appreciated.
A DataRow can contain many DataColumns. Even though your return DataRow contains only one DataColumn, you must still specify the DataColumn:
Dim results As String = ""
For Each row In Data1.Tables(0).Rows
results += row.Item(0).ToString() + "','" '<--- Added Item(0)'
Next
If results.Length > 2 Then
results = results.Substring(0, results.Length - 2)
End If
Also, double-check that you have an apostrophe for the first result. You might need:
Dim results As String = "'"
Finally, on an unrelated note, while the + operator can be used for string concatenation, I would recommend you use the & operator instead and only use + for numerical addition:
results &= row.Item(0).ToString() & "','" '<--- Added Item(0)'

too slow in show report in vb.net 2010 using crytal report

I am using this code to show the report
Dim rpt As New CrystalReport1()
Dim sql As String
Dim where As String
If con Is Nothing OrElse con.State = ConnectionState.Closed Then
'MsgBox("closed")
OpenCon()
End If
Dim m As String
m = ""
For Each n As TreeNode In GetCheck(TreeView1.Nodes)
If n.Tag = 1 Then
m = m
Else
If m = "" Then
m = (n.Tag)
Else
m = m & ", " & (n.Tag)
End If
End If
Next
sql = "SELECT [bran_id],[f01],[f02],[f03],[f04],[f05],[f06],[f07],[f08],[bran_name],[comp_id],[comp_name],'" & dtStart.Value.Date & "' AS start_date, '" & dtEnd.Value.Date & "' AS end_date FROM [v_complain]"
If m = "" Then
MsgBox("لم يتم تحديد اى مدينة من فضلك قم بالاختيار اولا")
Exit Sub
Else
where = " WHERE bran_id in (" & m & ") and f02 between CONVERT(date,'" & dtStart.Value.Date & "',103) and CONVERT(date,'" & dtEnd.Value.Date & "',103)"
sql = sql + where
If cbF06.Checked = True Then
where = " AND (f06 like N'') or (f06 is null)"
sql = sql + where
End If
If cbF07.Checked = True Then
where = " AND (f07 like N'') or (f07 is null)"
sql = sql + where
End If
Dim dscmd As New SqlDataAdapter(sql, con)
Dim ds As New DataTable
dscmd.Fill(ds)
rpt.SetDataSource(ds)
CrystalReportViewer1.ReportSource = rpt
CrystalReportViewer1.Refresh()
End If
con.Close()
but it's too slow to show the report in the first time. When I try to run it again without closing the window it work perfectly. Is there any way to make it faster?
Thanks
How slow it is? Several seconds?
I believe it happens do to a need to initialize underling reports 'engine'. I had similar issues and the best I could come up with was to display "Creating report, please wait..." message to a user so they. As an alternative, when you start your app, you can make a 'fake' call to create a dummy report in the background without displaying anything to a user so all required resources will be initialized by the time user is ready to create a real report.

problem in inserting list box value in visual basic 2008

i have a problem in inserting the listbox value into mysql database in vb 2008 i.e
if i select a video file i.e D:\videos\video1.mpg and add a msgbox() event before inserting into data base it shows the exact path i.e D:\videos\video1.mpg but when i check my database it shows me as D:videosvideo1.mpg how can i solve that...
here is my code
Dim check As String
Dim check_cmd As New MySqlCommand
Dim checklist As New MySqlDataAdapter
Dim listfile As String
Dim time As String
time = DateAndTime.Now
For L = 0 To bee_shed.Items.Count - 1
listfile = bee_shed.Items.Item(L)
check = "INSERT INTO schedule(id, listname, videofile, videoduration, videotime) VALUES('', '', '" & listfile & "', '' , '" & time & "')"
check_cmd.Connection = con
check_cmd.CommandText = check
checklist.SelectCommand = check_cmd
check_cmd.ExecuteNonQuery()
MsgBox(listfile)
Next
You're concatenating raw SQL statements and not escaping the backslash.
You must use parameters.
For example:
check_cmd.Connection = con
check_cmd.CommandText = "INSERT INTO schedule(id, listname, videofile, videoduration, videotime) VALUES('', '', ?filename, '' , ?time)"
For L = 0 To bee_shed.Items.Count - 1
listfile = bee_shed.Items.Item(L)
check_cmd.Parameters.Clear()
check_cmd.Parameters.Add("filename", MySqlDbType.VarChar, 80).Value = listfile
check_cmd.Parameters.Add("time", MySqlDbType.Something).Value = time
check_cmd.ExecuteNonQuery()
Next