Hey all i am in need of some ideas on how to go about doing the following:
I have a textbox that a user can type in an ID to search for in a database. It currently just checks for 1 ID.
Example:
User types in ID 645378
The Query would look like:
SELECT * FROM blahTable WHERE theID = '645378';
Now, i am looking to allow the user to type in more than 1 ID at a time and display those results.
So again an example would be:
User types in ID(s): 645378, 78664, 901524
And now this is where my question comes into play. How can i create a query based on how many ID's the user inputs into the textbox?
Any help would be great!
David
You could use the IN statement in SQL.
SELECT * FROM blahTable where theID in ('123','456','789')
I would advise implementing this via a parametrized query to avoid Bobby Tables (SQL Injection)
Just use IN:
SELECT * FROM blahTable WHERE theID IN (645378, 78664, 901524);
Note that if your values are actual strings and not numbers, then it will require some additional work:
Dim asValues As String()
Dim sbQuery As New System.Text.StringBuilder(5000)
' Get the text, but remove any embedded semi-colons and single quotes for sql injection'
asValues = Miles.Text.Replace(";", " ").Replace("'", " ").Split(New Char() {","c}, StringSplitOptions.RemoveEmptyEntries)
sbQuery.Append("SELECT * FROM blahTable WHERE theID IN (")
Dim fUseComma As Boolean
' Add each value to the query string. In this case, we are wrapping with '
For Each sValue As String In asValues
' Test the value for reasonableness (example only)'
If IsNumeric(sValue) Then
' Only use the comma starting from the second valid item added
If fUseComma Then
sbQuery.Append(",")
Else
fUseComma = True
End If
sbQuery.Append("'").Append(CInt(sValue)).Append("'")
End If
Next
sbQuery.Append(")")
cmd.CommandText = sbQuery.ToString
try this thing.
Dim xIDList As String = "645378, 78664, 901524" 'the user should separate ID by COMMA
Dim xID() As String = xIDList.Split(CChar(",")) 'splits the xIDlist
Dim xIDforQuery As String = String.Empty
For Each oID As String In xID
If oID.Trim.Length <> 0 Then
xIDforQuery &= "," & " '" & oID & "'" ' if ID is not numeric
' xIDforQuery &= "," & oID.ToString ' use this line if ID is numeric
End If
Next
xIDforQuery = xIDforQuery.Trim
xIDforQuery = CStr(IIf(Mid(xIDforQuery, 1, 1) = ",", Mid(xIDforQuery, 2, xIDforQuery.Length - 1), xIDforQuery))
Dim xFinalQuery As String = String.Empty
xFinalQuery = String.Format("SELECT * FROM blahTable where theID in ({0})", xIDforQuery)
' xFinalQuery is the final query statement but this approach is vulberable to SQL Injection.
How do users know which ID's they want? If there aren't too many ID's, using a multiple-selection list-box would improve the UI and simplify the code. If there are too many, then you might consider using an auto-complete text-box for users to choose items that can then be copied (removed) from a list-box to be used by the query.
Related
I am a PHP-MySql Guy & new to the vb.net & SQL Server CE.
how to handle records based on dates ?
Consider any table(tbl_demo) with with some columns having 1 column to store today's date.
For example (table structure)- Id Name today
-- ----- -----
int nvarchar datetime
If i have following data in a table -
Id Name today
-- ----- -----
1 vikram 11/08/2013 11:16:57 PM
then how do i retrieve this record by providing only 11/08/2013 to the query ?
PS-
I have facing following problem while executing the query (here is the code snippet) -
Dim Ddate As Date
Ddate = MonthCalendar1.SelectionRange.Start.ToString
SQLquery = "SELECT id,today FROM tbl_demo WHERE today = '" & Ddate & "'"
ERROR :The data type is not valid for the boolean operation.[Data type (if known) = datetime,Data type (if known) = nvarchar]
Though it is not best to have functions in the fields in the where clause (performance wise) this will do the job.
"SELECT id,today FROM tbl_demo WHERE CONVERT(DATETIME,CONVERT(VARCHAR,today,120)) = CONVERT(DATETIME,CONVERT(VARCHAR,'" & Ddate.ToString() & "',120))"
An alternative would be providing the Date directly to ISO format:
"SELECT id,today FROM tbl_demo WHERE CONVERT(DATETIME,CONVERT(VARCHAR,today,120)) = CONVERT(DATETIME,CONVERT(VARCHAR,'" & Ddate.ToString("yyyyMMdd") & "',120))"
I am not sure if it is yyyyMMdd or yyMMdd for SQL CE, so better try both.
According to this MSDN article it should be "yyMMdd" but it could be a typo...
While experimenting...I got this working as follows (please correct me if i wrong)
Dim Ddate As Date
Dim d, m, y
Ddate = MonthCalendar1.SelectionRange.Start.ToString
d = Ddate.ToString("dd")
m = Ddate.ToString("MM")
y = Ddate.ToString("yyyy")
And the Query is :
SQLquery = "SELECT billId,c_id,amount FROM tbl_outward WHERE (DATEPART(dd, ddate) = '" & d & "' AND DATEPART(mm, ddate) = '" & m & "' AND DATEPART(yyyy, ddate) = '" & y & "')"
Here's a complete example using a Data Reader. This is appropriate if you are going to process one row at a time. If you need to hold all the rows in memory or perform further operations you may want to use ExecuteDataSet to get the values.
This example prints the row values to the command line.
Dim recordDate as DateTime = new DateTime(2013,8,11)
Using connection As SqlCeConnection = New SqlCeConnection("Data Source=Database.sdf;Persist Security Info=False;")
connection.Open()
Using command As SqlCeCommand = connection.CreateCommand()
command.CommandText = "Select id, name, today from demo where today = #date"
Dim dateParameter As SqlCeParameter
dateParameter = New SqlCeParameter("#date", DbType.DateTime)
dateParameter.Value = recordDate
command.Parameters.Add(dateParameter)
Using reader As SqlCeDataReader = command.ExecuteReader()
Do While reader.Read()
Dim id As Integer = reader.GetInt32(0)
Dim name As String = reader.GetString(1)
Dim today As DateTime = reader.GetDateTime(2)
Console.WriteLine("{0,-4} {1,-10} {2,-10}", id, name, today)
Loop
End Using
End Using
End Using
A few important things to note:
The Using statements automatically clear up unused resources when you are finished with them
The sql statement used is parameterised, which allows you to pass in a strongly typed value rather than a string.
The first argument to Console.WriteLine is a string format. {0, -4} is a placeholder that will be filled by the next argument. -4 say that the value should be displayed left aligned in a column 4 characters wide. For more information, see the String.Format method documentation on MSDN.
I am getting a huge amount of data from my database which I before iterated through in a recordset like this:
sql = "select * from table"
set rs = conn.execute(sql)
if not rs.eof then
do until rs.eof
id = rs("id")
fullname = rs("fullname")
response.write("<a href='/" & id & "'>Hi " & fullname & ".<br />")
rs.movenext
loop
Now I am using a static recordset using GetRows() like this:
sql = "select * from table"
set rssql = conn.execute(sql)
if not rssql.eof then
rs = rssql.getrows()
end if
rssql.close
if isarray(rs) then
for counter = lbound(rs) to ubound(rs)
id = rs(0, counter)
fullname = rs(1, counter)
response.write("<a href='/" & id & "'>Hi " & fullname & ".<br />")
next
end if
Is it really not possible to do something like rs("id", counter) instead of using static numbers? I have a dynamic amount of coloumns (created by the system) in my table and it is very dynamic which of them I need. The number of coloumns I need in each rows are specificed by another coloumn in the row.
GetRows returns a vanilla array & as such is only addressable by a numeric index.
If you feel you need to dispose of the connection as soon as possible for some reason, you can fully populate the recordset and disconnect is as describe here.
(You can always use the initial recordset to populate another array or collection with the column names via the .Fields collection)
rs.Fields(counter).Name will give you access to column names. Unfortunately getrows() does not create an associative array, so you cannot look up data by column name.
I want to take the values from textboxes on a windows form and then update the values in the sql server database...I want to update only those fields for which a value has been entered by the user and leave the fields for which the textboxes are left empty by the user.....How can I generate the query dynamically for such a situation???
Edit:
I haven't yet coded for the update option...Here is my insertion code and i wanted to implement the update feature the same way just couldn't figure out how i can generate the query dynamically....It's a Booking System application
Dim str As String ' defines str as a string variable
'takes insertion query as a string in str variable
str = "Insert into Bookings Values(#cust_id, #cust_name,#contact, #game, #courtno, #poolno, #tableno, #booking_date, #booking_time, #booking_duration)"
'defines a new command which takes query string and connection string as parameters
Dim cmd As New SqlCommand(str, con)
' defines Customer ID parameter and takes its value from the form
Dim prmCustID As New SqlParameter("#cust_id", SqlDbType.Char)
prmCustID.Value = MskdTxtCustId.Text
' defines Customer Name parameter and takes its value from the form
Dim prmCustName As New SqlParameter("#cust_name", SqlDbType.Char)
prmCustName.Value = TxtCustName.Text
' defines Contact parameter and takes its value from the form
Dim prmContact As New SqlParameter("#contact", SqlDbType.VarChar)
prmContact.Value = MskdTxtCntctno.Text
' defines Game parameter and takes its value from the form
Dim prmGame As New SqlParameter("#game", SqlDbType.Char)
prmGame.Value = TxtGame.Text
' defines Court No parameter and takes its value from the form
Dim prmCrtNo As New SqlParameter("#courtno", SqlDbType.Int)
If TxtCrtNo.Text = "" Then
prmCrtNo.Value = Convert.DBNull 'If the textbox is empty then places Null in databse field
Else
prmCrtNo.Value = CType(TxtCrtNo.Text, Integer) ' converts from string to integer
End If
' defines Pool No parameter and takes its value from the form
Dim prmPoolNo As New SqlParameter("#poolno", SqlDbType.Int)
If TxtPoolNo.Text = "" Then
prmPoolNo.Value = Convert.DBNull 'If the textbox is empty then places Null in databse field
Else
prmPoolNo.Value = CType(TxtPoolNo.Text, Integer) ' converts from string to integer
End If
' defines Table No parameter and takes its value from the form
Dim prmTblNo As New SqlParameter("#tableno", SqlDbType.Int)
If TxtTblNo.Text = "" Then
prmTblNo.Value = Convert.DBNull 'If the textbox is empty then places Null in databse field
Else
prmTblNo.Value = CType(TxtTblNo.Text, Integer) ' converts from string to integer
End If
' defines Booking Date parameter and takes its value from the form
Dim prmBookDate As New SqlParameter("#booking_date", SqlDbType.DateTime)
prmBookDate.Value = TxtBookDate.Text
' defines Booking Time parameter and takes its value from the form
Dim prmBookTime As New SqlParameter("#booking_time", SqlDbType.DateTime)
prmBookTime.Value = TxtBookTime.Text
' defines Booking Duration parameter and takes its value from the form
Dim prmBookDur As New SqlParameter("#booking_duration", SqlDbType.Int)
prmBookDur.Value = CType(TxtBookDur.Text, Integer)
'Command cmd takes all the parameters
cmd.Parameters.Add(prmCustID)
cmd.Parameters.Add(prmCustName)
cmd.Parameters.Add(prmContact)
cmd.Parameters.Add(prmGame)
cmd.Parameters.Add(prmCrtNo)
cmd.Parameters.Add(prmBookDate)
cmd.Parameters.Add(prmBookTime)
cmd.Parameters.Add(prmBookDur)
cmd.Parameters.Add(prmPoolNo)
cmd.Parameters.Add(prmTblNo)
Dim str1 As String ' defines string variable for taking select query
str1 = "select bookingID from Bookings" 'takes select query in string variable for retrieving booking ID from the databse
Dim cmd1 As New SqlCommand(str1, con) 'defines a new command which takes query string and connection string as parameters
Dim x As Integer ' defines an integer for storing booking ID
con.Open() 'sets the connection state to open
Using (con) 'specifies the connection which is to be used by the SQLcommands
cmd.ExecuteNonQuery() 'Executes the insertion query
Dim id As SqlDataReader = cmd1.ExecuteReader() 'Defines and initiates the datareader to read data from database using cmd1 command
While id.Read() 'Iterates the reader to read booking id
x = id("bookingID") 'stores the booking Id in variable x
End While
id.Close()
End Using
con.Close() 'sets the connection state to close
' shows message box with successful booking message
MessageBox.Show("New booking saved successfully" & vbCrLf & "Your Booking ID is " & x, "Saved Successfully", MessageBoxButtons.OKCancel, MessageBoxIcon.Information)
this is a very broad question and highly dependend on what type of data-access framework your are going to use.
You could go low-level and use SqlCommand (if you use MsSql) or OdbcCommand to wrap up all with a SQL Update statement, with setters only for the fields you changed.
You could do dataset/datatable/dataadapter, load the row change only the fields you changed and update the table again.
You could do the same with LingToSql or EF.
If you want details please tell us what you tried and what you want to use.
I'm building a dynamic query in my ASP.NET MVC project by the following:
Dim queryString As String = "SELECT VALUE userInfos FROM MyDBEntities.UserInformations AS userInfos"
If strWhere <> "" Then
queryString = queryString & " WHERE " & strWhere
End If
' Call the constructor with the specified query and the ObjectContext.
Dim SearchUsersQuery As New System.Data.Objects.ObjectQuery(Of UserInformation)(queryString, MyDB)
Dim lstOfUsers As List(Of UserInformation) = SearchUsersQuery.ToList
Where basically the strWhere is a string that I build up a dynamic filter depending on what the user selects to search on.
This works great until I need to add a date comparison to the date clause.
I'm trying the following:
strWhere = " userInfos.BirthDate <= " & StartDateForQuery.ToShortDateString
Which will end up as:
"SELECT VALUE userInfos FROM MyDBEntities.UserInformations AS userInfos Where userInfos.BirthDate <= 10/09/1992"
But when i try to execute the query with the ToList whenever a date is in the where string i get the following error:
The argument types 'Edm.DateTime' and 'Edm.Int32' are incompatible for this operation. Near WHERE predicate, line 1, column 103.
Any ideas on what my issue is?
Thanks in advance
You can't compare dates that way.
When you do this:
"SELECT VALUE userInfos FROM MyDBEntities.UserInformations AS userInfos
WHERE userInfos.BirthDate <= 10/09/1992"
10/09/1992 is being interpreted as an Int value.
Try putting single quotes around this value as in:
"SELECT VALUE userInfos FROM MyDBEntities.UserInformations AS userInfos
WHERE userInfos.BirthDate <= '10/09/1992'"
Probably you'll have to call a database date conversion function (depends on your database vendor) passing to it this date string.
Like this:
"SELECT VALUE userInfos FROM MyDBEntities.UserInformations AS userInfos
WHERE userInfos.BirthDate <= DataBaseSpecificToDateFunction('10/09/1992')"
The problem is that this query is being sent to the database and is the database server that'll execute it. That's why you need a database specific date conversion function.
For example: in Oracle we have the to_date function to convert a string to a datetime using a given pattern:
to_date('1998/05/31:12:00:00AM', 'yyyy/mm/dd:hh:mi:ssam')
In SQL Server we have the convert function as in:
convert(datetime, '2016-10-23 20:44:11',20) -- yyyy-mm-dd hh:mm:ss(24h)
More samples here.
Why don't you use the next code:
Dim queryString As String = "SELECT VALUE userInfos FROM MyDBEntities.UserInformations AS userInfos"
' Call the constructor with the specified query and the ObjectContext.
'
Dim SearchUsersQuery As New System.Data.Objects.ObjectQuery(Of UserInformation)(queryString, MyDB)
'verify if should be a startdate for adding to query
'
If StartDateForQuery <> "" Then
'add the condition to the query
'
SearchUsersQuery = SearchUsersQuery.Where("it.BirthDate <= #BirthDate ")
'add the parameter to be used
'
SearchUsersQuery.Parameters.Add(New ObjectParameter("BirthDate ", StartDateForQuery))
End If
Dim lstOfUsers As List(Of UserInformation) = SearchUsersQuery.ToList
You make use of the linq capabilities to generate queries (it "knows" how to generate the datetime parameter for DB query).
Check a sample here
In a SQL database I have a table, Table1. This table is related to another table, Table2 which in turn is related to Table3. There is a query Query1 that selects certain records from Table1.
This database is linked to in an Access database project
A form Table1Data is based on Table1, with a datasheet containing related Table2 data (and subsequently Table3 data). This form is opened by another form (Switchboard). The problem comes when the form is opened. I want the form to be filtered, but when I set up a macro and open the form and set the Filter to Query1, the data in the form is not filtered. Why does this happen, is this not the way to do it? Query1 selects all the columns from Table1, so mismatching columns should not be an issue.
Additionally I want to lock it down - only certain people can execute Query1, same with other queries (Query2, Query3 etc). So they can only edit the data that they are permitted to edit.
My preferred solution is to set the recordsource in the Form Open event. This gives me the most control over what is going on.
Here is my boilerplate for doing this. It also includes looking up the OpenArgs which are passed on calling the form. You can just comment out or remove the If/Then statement if you aren't looking to specify anything from the calling form in your SQL.
Private Sub Form_Open(Cancel As Integer)
' Comments :
' Parameters: Cancel -
' Modified :
' --------------------------------------------------
On Error GoTo Err_Form_Open
Dim strSQL As String
Dim strVariable As String
Dim strDateVariable As String
Dim dteDateVariable As String
Dim i As Integer
Dim n As Integer
'Get variables from Left and right of | in OpenArgs
If Not (IsNull(Me.OpenArgs)) Then
i = InStr(1, Me.OpenArgs, "|")
n = Len(Me.OpenArgs)
strVariable = Left(Me.OpenArgs, n - (n - i + 1))
strDateVariable = Right(Me.OpenArgs, (n - i))
dteDateVariable = CDate(strDateVariable)
Else
GoTo Exit_Form_Open
End If
strSQL = "SELECT ... " _
& "FROM ... " _
& "WHERE (((Field1)='" & strVariable & "') " _
& " AND ((Field2)=#" & dteDateVariable & "#));"
Me.RecordSource = strSQL
Me.Requery
Exit_Form_Open:
Exit Sub
Err_Form_Open:
Select Case Err.Number
Case Else
Call ErrorLog(Err.Number, Err.Description, "Form_Open", "frmName", Erl)
GoTo Exit_Form_Open
End Select
End Sub