I cannot seem to figure out how to get an output of a SQL query as a variable in VB. I need something like what's below so that I can use that variable in another SQL query. SQL doesn't allow the use of variables as column headers when running queries, so I thought I could use VB to insert the actual output of one SQL task as the dynamic variable in a loop of update queries. Let me (hopefully) explain.
I have the following query:
DECLARE #id int = (SELECT max(id) FROM [views]), #ViewType nvarchar(3);
WHILE #id IS NOT NULL
BEGIN
SELECT #ViewType = (SELECT [View] FROM [views] WHERE id = #id);
UPDATE a
SET a.[#ViewType] = '1'
FROM [summary] a
INNER JOIN [TeamImage] b
ON a.[Part_Number] = b.[PartNum]
WHERE b.[View] = #ViewType;
SELECT #id = max(id) FROM [views] WHERE id < #id;
END;
The SET a.[#ViewType] = '1' obviously will not work in SQL. But if I could have the (SELECT [View] FROM [views] WHERE id = #id) equal to a variable, then I could write the SQL query in VB and execute it and the variable would become part of the string and therefore execute correctly.
I'm newer to VB, but here's what I have so far:
Dim cn As SqlConnection = New SqlConnection("Data Source=Server1;" & _
"Initial Catalog=DB1;" & _
"Integrated Security=SSPI")
cn.Open()
Dim cmd As New sqlCommand("SELECT max(id) FROM orientation_view_experiment;", cn)
vID = cmd.ExecuteNonQuery()
Do While vID > 0
Dim cmd2 As New sqlCommand("SELECT [View] FROM [views] WHERE id ='" + vID + "'"
vViewType = cmd2.ExecuteNonQuery()
Dim cmd3 As New sqlCommand("UPDATE a
SET a.'" + vViewType + "' = '1' & _
FROM [summary] a & _
INNER JOIN [TeamImage] b & _
ON a.[Part_Number] = b.[PartNum] & _
WHERE b.[View] = '" + vViewType + "';"
cmd3.ExecuteNonQuery()
vID = vID - 1
Loop
cn.Close()
I hope some of that made sense, but I'm kind of lost at this point. I feel like I know what I need the SQL to do, but can't quite figure out how to make the computer/programs submit to my will and just do what I need it to do.
Thank you for any help/direction you can give.
Your code is wrong because you insist in using ExecuteNonQuery for SELECT statements. ExecuteNonQuery doesn't return the rows selected but just a count of the rows affected by an INSERT/DELETE/UPDATE query (I think that for SELECT it returns always zero)
What you need is ExecuteScalar to get the MAX value and the VIEW value because ExecuteScalar is the best choice when you expect to get just the first field of the first row from your SQL statement
Dim cmd As New sqlCommand("SELECT max(id) FROM orientation_view_experiment;", cn)
vID = Convert.ToInt32(cmd.ExecuteScalar())
Do While vID > 0
Dim cmd2 As New sqlCommand("SELECT [View] FROM [views] WHERE id =" + vID.ToString()
Dim result = cmd2.ExecuteScalar()
if Not string.IsNullOrEmpty(result)) Then
vViewType = result.ToString()
Dim cmd3 As New sqlCommand("UPDATE a SET a.[" + vViewType + "] = '1' " & _
"FROM [summary] a " & _
"INNER JOIN [TeamImage] b " & _
"ON a.[Part_Number] = b.[PartNum] " & _
"WHERE b.[View] = #vType"
cmd3.Parameters.AddWithValue("#vType", vViewType)
cmd3.ExecuteNonQuery()
End If
Loop
The last part of your code is not really clear to me, but you could use a couple of square brackets around the column name in table summary and a parameter for the View field in table TeamImage.
As a last advice, be sure that the column View in table TeamImage is not directly modifiable by your end user because a string concatenation like this could lead to a Sql Injection attacks
Do a little research into what the different methods of a command are. When you call ExecuteNonQuery, this return the number of records effected. I think you want ExecuteScalar as your cmd and cmd2 methods, so you can get a value from the database.
Have you tried replacing '" + vViewType + "' with [" + vViewType + "] ... in other words use square brackets to delimit the column name instead of single quotes which are for delimiting string literals?
Also, I would encourage stopping in the debugger, examining the command that you generated into cmd3 and try executing it directly. It might help you identify other similar problems such as the fact that vViewType is giving you a count of records instead of an actual value from the [View] column.
Related
My database program has a statement like:
variable = "SELECT * from Staff where StaffName = '" & cStaffName & "'"
This works fine until I have a member of staff with ' (apostrophe) in there name as it ends the start apostrophe.
SELECT * from Staff where StaffName = 'O'Conner'
Is there a way around this without replacing the apostrophe in her name?
You just need to use a parameterized query.
Using con = new SqlConnection(....)
Using cmd = new SqlCommand("SELECT * from Staff where StaffName = #name", con)
con.Open
cmd.Parameters.Add("#name", SqlDbType.NVarChar).Value = cStaffName
Using reader = cmd.ExecuteReader
.....
End Using
End Using
End Using
In this scenario you add a parameter to the SqlCommand parameters collection. The command text has no more a string concatenation but contains a parameter placeholder (#name). The parameter itself contains the value you want to pass to your query.
In this way there is no problem with quotes embedded in the value.
You also get the extra benefit to avoid any kind of Sql Injection problem with the user input
variable = "SELECT * from Staff where StaffName = '" & Replace(cStaffName, "'", "\'") & "'"
My command is error in my sql command where clause, how can I handle it? any suggestion or any help?
This is my Error:
syntax to use near 'WHERE controlNumber = '' at line 1
cmd = New Odbc.OdbcCommand("INSERT INTO alamnotice (correctivePreventive) VALUES('" & Trim(txtremarks.Text.TrimEnd()) & "') WHERE controlNumber ='" & Trim(Form1.txtcontrolNumber.Text.TrimEnd()) & "'", con)
cmd.ExecuteNonQuery()
You havent said what the error is, it could be something to do with Disconnect, but I suspect it is a SQL syntax error because INSERT doesnt use a WHERE (you are inserting new data).
Here is a way to use params to make the code easier to read and avoid SQL injection attacks:
Dim SQL As String = "INSERT INTO alamnotice (correctivePreventive,
sectionInCharge, shiftInCharge, SectionHead, status,
dateResponded, remarksSurrendingAlarm, Remarks)
VALUES ("#p1", "#p2", "#p3", "#p4", "#p5", "#p6", "#p7", "#p8")"
' I am assuming OleDB, but much the same for others
' be sure to add the values in the same order with OleDB
Using cmd As New OleDbCommand(SQL, dbCon)
cmd.Parameters.AddWithValue("#p1", txtcorPrevAction.Text )
cmd.Parameters.AddWithValue("#p2", txtCause.Text)
cmd.Parameters.AddWithValue("#p3", cmbstatus.Text)
' etc
cmd.ExecuteNonQuery()
End Using
for non string columns, such as a date, convert the textbox text:
cmd.Parameters.AddWithValue("#pX", COnvert.ToInt32(txtSomeValue.Text))
the code is easier to read and if you arent gluing ticks and stuff into a string, there are far fewer string format errors like a missing '
try this one :
UPDATE alamnotice SET correctivePreventive = '" & Trim(txtremarks.Text.TrimEnd()) & "' WHERE controlNumber ='" & Trim(Form1.txtcontrolNumber.Text.TrimEnd()) & "'"
Simple enough, I can't figure out how to add (that's +) an integer from a textbox to the integer in the SQL Field.
So for example, the SQL Field may have '10' in it and the textbox may have '5' in it. I want to add these numbers together to store '15' without having to download the SQL Table.
The textbox that contains the integer to be added to the SQL integer is tranamount.Text and the SQL Column in the SQL Table is #ugpoints. Please note, without the '+' - which is in the below code and is admittedly wrong- the value of tranamount.Text is added to the Table without an issue, but it simply replaces the original value; meaning the end result would be '5' in the SQL Field.
What would be the proper way to structure this? I've tried the below code, but that clearly doesn't work.
cmd = New SqlCommand("UPDATE PersonsA SET U_G_Studio=#ugpoints WHERE Members_ID=#recevierID", con)
cmd.Parameters.AddWithValue("#recevierID", tranmemberID.Text)
cmd.Parameters.AddWithValue("#ugpoints", + tranamount.Text) '<--- Value to add.
cmd.ExecuteNonQuery()
Newbies question I know, I'm new to SQL in vb.
You have to use the correct sql:
Dim sql = "UPDATE PersonsA SET U_G_Studio=U_G_Studio + #ugpoints WHERE Members_ID=#recevierID"
Also use the correct type with AddWithValue:
Using cmd = New SqlCommand(sql, con)
' use the using-statement to dispose everything that implements IDisposable, so also the connection '
cmd.Parameters.AddWithValue("#ugpoints", Int32.Parse(tranamount.Text))
' .... '
End Using
Take the current value of the U_G_Studio field, add the value of the parameter and reassign to U_G_Studio, but keep in mind that you need to pass the value as an integer because otherwise the AddWithValue will pass a string and you get conversion errors coming from the db.
cmd = New SqlCommand("UPDATE PersonsA SET U_G_Studio=U_G_Studio + #ugpoints " &
"WHERE Members_ID=#recevierID", con)
cmd.Parameters.AddWithValue("#recevierID", tranmemberID.Text)
cmd.Parameters.AddWithValue("#ugpoints", Convert.ToInt32(tranamount.Text))
cmd.ExecuteNonQuery()
The SQL you want is:
"UPDATE PersonsA SET U_G_Studio= (U_G_Studio + #ugpoints) " & _
"WHERE Members_ID=#recevierID"
what about
cmd.Parameters.AddWithValue("#ugpoints", (int)tranamount.Text)
....
cmd = New SqlCommand("UPDATE PersonsA SET U_G_Studio= SET U_G_Studio + #ugpoints WHERE Members_ID=#recevierID", con)
edit1: STEVE WAS FASTER!
I have a very simple database in Access 2007 that I'm connecting to using VB 2010. There are two tables, MenuItems and Orders, and Orders.orderDate is of type "Date".
I'm running the following code in one of my VB forms (the connection string and everything else is fine):
sql = "SELECT OrderDate, MenuItem FROM MenuItems, Orders WHERE Orders.itemID = MenuItem.ID AND Orders.orderDate BETWEEN '" + fromDate + "' AND '" + toDate + "'"
Dim cmd As New OleDb.OleDbCommand(sql, con)
Dim count As Integer = cmd.ExecuteNonQuery()
But I get an error that:
System.Data.OleDb.OleDbException (0x80040E10): value wan't given for one or more of the required parameters
Nothing seems to be missing. I've used the same code for another query, except the sql was different. But I think my sql is simple enough. Here's the sql that was generated in one instance (I've double checked, all table and column names are correct):
SELECT OrderDate, MenuItem From MenuItems, Orders WHERE Orders.itemID = MenuItem.ID AND Orders.orderDate BETWEEN '11/21/2012' AND '11/24/2012'
You should use parametrized queries for at least two reasons.
You don't have to worry about date (and other) literals and locale problems.
You don't have to worry about SQL injection attacks, where someone enters malicious code in a text box that turns a SQL statement into a harmful one.
Change your statement to
sql = "SELECT Orders.OrderDate, MenuItems.MenuItem " & _
"FROM MenuItems INNER JOIN Orders ON MenuItems.ID = Orders.itemID " & _
"WHERE Orders.orderDate BETWEEN ? AND ?"
Then execute the command like this
Dim fromDate, toDate As DateTime
fromDate = DateTime.Parse(fromDateTextBox.Text)
toDate = DateTime.Parse(toDateTextBox.Text)
Dim dataset As New DataSet()
Using conn As New OleDbConnection(connectionString)
Using adapter As New OleDbDataAdapter()
Dim cmd As New OleDbCommand(sql, conn)
cmd.Parameters.Add("?", fromDate)
cmd.Parameters.Add("?", toDate)
adapter.SelectCommand = cmd
adapter.Fill(dataset)
End Using
End Using
Well, the ExecuteNonQuery method is there for statements for changing data, ie. DELETE / UPDATE /INSERT, and the returned value are the number of rows affected by that statement.
Since you are using Select statement, you should be using oledbDataAdapter and Fil DataSet for use.
Dim conn As New OleDbConnection(con)
Dim adapter As New OleDbDataAdapter()
sql = "SELECT OrderDate, MenuItem FROM MenuItems, Orders WHERE Orders.itemID = MenuItem.ID AND Orders.orderDate BETWEEN '" + fromDate + "' AND '" + toDate + "'"
adapter.SelectCommand = new OleDbCommand(sql, con)
adapter.Fill(dataset)
Return dataset
The issue was a mis-spelled table. (MenuItem instead of MenuItems), but it didn't solve the question, I still got an error. It turned out to be a problem with matching formats between the database and the datepicker values being used as query parameters.
So I made sure I saved to the database in short Date Format:
sql = "INSERT INTO Orders(itemID, OrderDate) VALUES('" + ListBox1.SelectedValue.ToString() + "','" + FormatDateTime(OrderDate.Value, DateFormat.ShortDate) + "')"
hie all,
i want to insert the data into the table only if the table is empty, so for that i need to check the condition to check whether data already exists in the table, if present then i want to empty the table before inserting the the fresh value.
i know how to insert and delete the data only prob is to check the condition. so please can any help me out in this.
TO INSERT
Dim comUserSelect As OleDbCommand
myDateTime(i) = DateTime.Parse(arr_dateTime(i))
' Console.WriteLine(r("P1"))
Dim strSELEsCTa As Integer = r("P1")
If ins < 10 Then
ins = ins + 1
Dim strSELECTa As String = "insert into tblvalues (DataTime ,P1) values ('" & DateTime.Parse(arr_dateTime(i)) & "','" & strSELEsCTa & "')"
Dim dadte_s As New OleDbDataAdapter(strSELECTa, conn)
comUserSelect = New OleDbCommand(strSELECTa, conn)
comUserSelect.ExecuteNonQuery()
End If
*TO DELETE *
Dim strDelete As String = "delete * from tblvalues "
now i don know how to check the condition
"SELECT COUNT(*) FROM your_table_name"
If the table is empty, this should return 0.
Alternatively, you could try to select a row from the table and based on the response act upon it.
"SELECT * FROM your_table_name LIMIT 0, 1"