UPDATE same column multiple times in query - sql

Is there a specified behavior for updating the same column 2+ times in the same UPDATE query, as follows?
UPDATE tbl SET a = 5, b = 'something', a = 6 WHERE c = 'whatever';
Is there a standardized behavior for this, or might it vary between flavors of SQL (e.g. it is "undefined behavior")? A cursory test with sqlite seems to indicate they are executed left-to-right, so the last column value will be the resulting one, but that doesn't imply that will always be the case.
Edit: The reason I'm trying to do this is I'm testing some SQL injection for a class project. One of the fields in an UPDATE is unsafely injected, and I'm trying to use it to overwrite previously SET fields from the same query.

This isn't exactly the answer you're looking for but assuming that the text "something" is a field you are passing in and it isn't parameterized or escaped you may be able to do this. This all depends on how the query is being built and what database it is being run against.
UPDATE tbl SET a = 5, b = 'something'; UPDATE tbl set a = 6;--' WHERE c = 'whatever';
by entering the following in the user input
something'; UPDATE tbl set a = 6;--
This assumes that the query is built dynamically something like this
var query = "UPDATE tbl set a = 5, b = '" + userInput + "' WHERE c = 'whatever'";
Here is a relevant question: How does the SQL injection from the "Bobby Tables" XKCD comic work?

Related

MS Access SQL Switch Function

I have several tables with the same data structure (they're filled with a bunch of stuff, in separate .accdb files to account for the 2GB limit) and need to retrieve info from one of them based on a field in a form.
Upon researching I came up with the following, but it won't seem to work.
SELECT MyNumber, MyName, MyPage, MyDrawing
FROM Switch([Forms]![View_Info]![Contract] = "Contract1", "tblContract1", [Forms]![View_Info]![Contract] = "Contract2", "tblContract2")
WHERE (MyNumber = [Forms]![View_Info]![MyNumber])
Syntax error in FROM clause.
In this example I only used 4 fields and 2 tables but in fact there are around 9 tables and 20 fields in each that I wish to retrieve.
Can someone shed some light on this? I have a really hard time with SQL, so I apologize if this is quite basic.
Thanks in advance, Rafael.
You cannot return the table name from a function in the SQL FROM clause. If your table is determined dynamically, then you must build the SQL command string dynamically.
Dim tableName As String, sql As String
tableName = Switch(...)
sql = "SELECT ... FROM [" & tableName & "] WHERE ..."
As #forpas explains in his answer, you can use a UNION query, but this will always query all the tables. Since the filter is not based on a table column, the filtering will occur on the client side, i.e. in your application.
Try this UNION:
SELECT MyNumber, MyName, MyPage, MyDrawing
FROM tblContract1
WHERE (MyNumber = [Forms]![View_Info]![MyNumber]) AND [Forms]![View_Info]![Contract] = "Contract1"
UNION
SELECT MyNumber, MyName, MyPage, MyDrawing
FROM tblContract2
WHERE (MyNumber = [Forms]![View_Info]![MyNumber]) AND [Forms]![View_Info]![Contract] = "Contract2"
Each query of the UNION contains in the WHERE clause the condition:
[Forms]![View_Info]![Contract] = "Contract?"

Dynamically create sql where condition on textbox entry

I am working on a C# desktop application. I want to create a search functionality. Now the problem is that i am using around 8 textboxes. Different permutations of textboxes could be populated and the resulting 'sql where' condition should only include those textboxes values which are not null. Now one pathetic way is to use a zillion 'if and else' which obviously is laborious. Any other way to do this?
You need just one query with filled WHERE to use all parameters like this
select ...
from ...
WHERE
(firstNameColumn=:firstNameParam or :firstNameParam is null)
AND (lastNameColumn=:lastNameParam or :lastNameParam is null)
AND (...)
I would like to make a point of first checking is the paramtere null, then use it to compare with column values.
Since you are generating query in C#, try old-Chinese approach from Ming period of using default condition where 1=1 just to avoid checking did you already had first condition :)
string query = "select ... from ... join ... on ... where 1=1";
//suposedly you have value of one search box in variable called "item_name"
if(string.IsNullOrWhiteSpace(item_name) == false)
{
query += " and Order_Line.Name ='" + item_name + "'";
}
and so on for other fields.
What you are trying to do in order to avoid ifs is not really a good approach. Look at this:
string query = " select ... where Order_Line.Name = '" + item_name + "'";
What will be the resulting string if item_name is actually null?
EDIT: the resulting query would be
where Order_Line.Name = '' or Order_Line.Name is null
which is not what you want. You want every row if that search field is empty, menaing it shouldn't have anu effect on search. That's why you need condition to see will you include this column in where clause in the first place.

VBA / Visual Basic. Simple String SQL

I'm creating a Voting System. so it's like this every time A Button1 is pressed + 1 or it will increase the vote in the Access database. I can't find anything in Google.
trx = "update [Table1] SET [Vote] = Vote + 1, (WHERE ID = 1)"
Don't include a comma before the WHERE clause. Also you don't need to put the WHERE clause inside parentheses.
Test this as a new query in the Access query designer.
update [Table1] SET [Vote] = Vote + 1 WHERE ID = 1
Fine tune as needed. And once you have it working in the query designer, adapt your VBA code to use that working statement.
Remove comma before Where and brackets around where clause
trx = "update [Table1] SET [Vote] = Vote + 1 WHERE ID = 1"

How do I run an SQL update query using a like statement

I am trying to update a field in a table using an SQL update query where there is a like statement referencing a value in another table. They syntax unfortunately is not working. Below is my code. In short, I am trying to put a '1' in the field 'Query07ParolaChiave' in the table 'tblSearchEngine01' when the value located in table 'tblsearchengine07' is present in the field 'tblMasterListOfEventsNotes' located in the table 'tblSearchEngine01'. I think my code is almost complete but there is a syntax issue which i cant find.
st_sql = "UPDATE tblSearchEngine01, tblSearchEngine07 SET tblSearchEngine01.Query07ParolaChiaveSelect = '1' WHERE ((([tblSearchEngine01].[tblMasterListOfEventsNotes]) Like " * " & [tblsearchengine07].[ParolaChiave] & " * "))"
Application.DoCmd.RunSQL (st_sql)
I suggest you 2 solutions :
This one is using EXISTS functions, and will check for each row in tblSearchEngine01 if there is a matching value in tblsearchengine07
UPDATE
tblSearchEngine01
SET
tblSearchEngine01.Query07ParolaChiaveSelect = '1'
WHERE
EXISTS (SELECT 1
FROM tblsearchengine07
WHERE [tblSearchEngine01].[tblMasterListOfEventsNotes] Like '*' & [tblsearchengine07].[ParolaChiave] & '*')
This one is more performant because it uses JOIN
UPDATE
tblSearchEngine01
INNER JOIN tblsearchengine07
ON [tblSearchEngine01].[tblMasterListOfEventsNotes] Like '*' & [tblsearchengine07].[ParolaChiave] & '*'
SET
tblSearchEngine01.Query07ParolaChiaveSelect = '1'
I read something like in ADO/VBA, you have to use % instead of * as the wildcard.
You can have more information on wildcard and LIKE comparator here
UPDATE
Why the '1' after select in your first solution?
EXISTS (SELECT 1 ... is better for performance because it return only the number 1 instead of fields, anyway EXISTS just stop the excecution after 1 element found.
'Performant' means more consuming in regards to space and memory?
JOIN is more performant in term of time of execution, RDBMS are far better at joining tables than using subquery, in some rare case, it's more interesting to use the 1st solution.
Also, any initial thoughts as to why my original solution (coming straight from an Access Query which works) does not function?
I cannot really know but perhaps it's because of " * ", because you are saying SPACE + * + SPACE + VALUE + SPACE + * + SPACE. For ex : 'John' LIKE ' John '
May be with "*" instead of " * " could solve it...
I have no other track, I'm not Access sql developper, I usually play around Sql server/Oracle/mySql, hope it helped. ;)
Try to change your like this way:
... Like '*" & tblsearchengine07.parolachiave & "*'))"
The like statement go into the WHERE clause.
If you do want to use LIKE without you care about caps letters, then you can use it like this:
LIKE COLUMN_NAME = '%WhatYouLike%'
My suggestion is:
Use a table variable (#Table) with a unique/primary key coming from the table to be updated.
SELECT all the data to be updated (you can add the like statement here) and then INSERT that in the created table variable.
Construct the UPDATE statement with an INNER JOIN to the table variable matching with the unique/primary key.
I know this may take a lot of steps but believe me these are more efficient than using a black list approach.

Deleting data from Access with VBA

I'm trying to delete every record from my current Access database in VBA where OTP = txtOTP.value and VARIABLE = {NomAdminContrats,TelAdminContrats,TelecAdminContrats, [...]}
Here is my code:
Dim query As Recordset
Set query = CurrentDb.Execute("DELETE * FROM tb_SOMMAIRE WHERE OTP = '" & txtOTP.value & "' AND (VARIABLE = 'NomAdminContrats' or VARIABLE = 'TitreAdminContrats' or VARIABLE = 'UnitAdminContrats' or VARIABLE = 'AdrAdminContrats' or VARIABLE = 'VilleAdminContrats' or VARIABLE = 'TelAdminContrats' or VARIABLE = 'TelecAdminContrats' or VARIABLE = 'CourrielAdminContrats')")
I got an error 3219 Invalid Operation when trying with OpenRecordset or Expected function when trying with Execute. I've tried a lot of things but I didn't manage yet to get this query working. I also have the full table in a recordset, would it be easier/faster to do it with myRecordset.Delete? If so, how could I do it?
EDIT
Now trying with CurrentDb.Execute instead of CurrentDb.OpenRecordset. The error is now Function expected instead of Invalid Operation.
You were not supposed to use parentheses for the recordset.execute function, unless you want to send the execute function options, as well as your query.
currentDB.Execute ("SQL EXECUTABLE QUERY", Options)
options is an optional constant that you can include in the function, such as dbDenyWrite, or dbFailOnError. when you don't include options in your execute function, Microsoft uses the default dbInconsistent, and you should not use parentheses.
Set query = CurrentDb.Execute "DELETE * FROM tb_SOMMAIRE..."
The reason your code worked when you used the variable sql is because you did not use the parantheses when you used the variable.
You already solved the problem. Congratulations. See whether a different approach for your WHERE clause is easier to work with.
The WHERE clause checks whether VARIABLE matches a list of values. Instead of using multiple OR conditions to compare VARIABLE with each member of the list, you can simply ask the db engine whether VARIABLE is present IN the list of values.
AND
(
[VARIABLE] IN
(
'NomAdminContrats',
'TitreAdminContrats',
'UnitAdminContrats',
'AdrAdminContrats',
'VilleAdminContrats',
'TelAdminContrats',
'TelecAdminContrats',
'CourrielAdminContrats'
)
)
Finally managed to get it working. Had to declare another var for the query for some reason.
Dim sql as String
sql = "DELETE * FROM tb_SOMMAIRE WHERE OTP = '" & txtOTP.value & "' AND (VARIABLE = 'NomAdminContrats' or VARIABLE = 'TitreAdminContrats' or VARIABLE = 'UnitAdminContrats' or VARIABLE = 'AdrAdminContrats' or VARIABLE = 'VilleAdminContrats' or VARIABLE = 'TelAdminContrats' or VARIABLE = 'TelecAdminContrats' or VARIABLE = 'CourrielAdminContrats')"
CurrentDb.Execute sql