Deleting data from Access with VBA - sql

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

Related

Passing multiple Excel cell values to SQL query WHERE clause without referencing other queries

I have an SQL view, MyView, containing the column ID of type nvarchar.
I wish to create an Excel query which:
takes the values from a column in an Excel sheet,
composes a string corresponding to a WHERE clause for the ID column,
calls the SQL query using this parameter string.
As far as I can tell, I am trying to achieve something very analogous to
Excel cell Value as SQL query where statement
My solution is working fine on my own computer. However, when I try to share my solution with a colleague who has the same reading permissions for the database, I end up with a 'query referencing another query' problem which throws a formula.firewall error, and no data is loaded.
My solution is as follows:
I have created a data connection, Parameters, from the column named ID in Excel which contains my ID values:
let
Source = Excel.CurrentWorkbook(){[Name="Parameters"]}[Content],
#"Changed type" = Table.TransformColumnTypes(Source,{{"ID", type text}})
in
#"Changed type"
Next, I create my parameter string as a new data source, fnGetParameters:
let
Source = Excel.CurrentWorkbook(){[Name="Parameters"]}[Content],
AddString = Table.AddColumn(Source, "Custom", each "ID = " & "'" & [ID] & "' OR "),
RemoveID = Table.SelectColumns(AddString,{"Custom"}),
Custom = Text.Combine(RemoveID[Custom], ""),
Parameter = Text.Start(Custom,Text.Length(Custom)-4)
in
Parameter
which creates a nice string looking like e.g. 'ID = '1' OR ID = '2' OR ID = '3'' depending on the values in the column ID in Parameters.
Finally, I try to create my query:
let
Source = Sql.Database("MyServer", "MyDatabase",[Query="
SELECT *
FROM [MyDatabase].[dbo].[MyView]
WHERE " & fnGetParameters])
in
#"Source"
Incidentally, when removing the WHERE clause from the code above, it works fine on any computer:
let
Source = Sql.Database("MyServer", "MyDatabase",[Query="
SELECT *
FROM [MyDatabase].[dbo].[MyView]"])
in
#"Source"
so it is somehow the addition of the parameter string which causes an error.

How to use VBA variable for IN 'SourceDB' clause of MS-ACCESS query

I am trying to pass a vba string variable to an IN clause of a SQL statement in the query builder view.
the string is created by the following function:
Public Function GetBackEnd()
If Len(GetBackEnd) = 0 Then GetBackEnd = BackEnd
End Function
backend itself is derived from a dropdown box in userform, there are two entries in a table with two different addresses, one each for the live and developement DB's. The dropdown box sets the "environment" variable upon selection.
Property Get BackEnd() As String
Select Case Environment
Case Is = "Development"
BackEnd = DLookup("VariableValue", "Globals", "Variable= 'TestEnvironment'")
Case Else
BackEnd = DLookup("VariableValue", "Globals", "Variable= 'Backend'")
End Select
End Property
I have tried a couple of variations on the following but get an error each time.
SELECT *
FROM TableName IN 'GetBackEnd()';
I imagine its something simple but after staring at this for so long Ijust can't see it.
thank you.
Generally, you can do what you want - use a function to provide parameter strings.
Public Function GetName() As String
GetName = "foo"
End Function
SELECT * FROM bar WHERE floo = GetName()
But in some parts / cases, you can't use variables. Both IN clauses are among them.
These won't work:
GetInList = "'x', 'y', 'z'"
SELECT * FROM bar WHERE floo IN (GetInList())
and your use-case is not possible either:
GetDbPath = "C:\path\myDb.accdb"
SELECT * FROM bar IN GetDbPath()
You will have to construct the whole SQL on the fly:
Db.QueryDefs("myQuery").SQL = "SELECT * FROM TableName IN '" & GetBackEnd() & "'"
Missing WHERE clause in SQL query? Let's say
SELECT *
FROM TableName
WHERE Name = GetBackEnd;

Variable Inside the Access Pass Through Query

I set a global variable in my program.
public this_is_global_var as integer
this_is_global_var=1
Then I use that variable inside my pass through query
Select * from oracle_table where id=this_is_global_var ;
But error shows "this_is_global_var: invalid identifier"
Please help.Thanks.
You can define placeholders for variable inside the query definition and replace it before execution.
qdfTemp.SQL = Replace(qdfMyQuery.SQL, "[this_is_global_var]", str(this_is_global_var))
and then execute temp query. Original query will be untouched.
If you want to use variables in your query you have to write it as a variable:
"SELECT * FROM oracle_table WHERE id = " & this_is_global_var

Expected function / variable error message

i am trying to write a simple append query using SQL for my access database. Upon trying to execute the code, the message i am getting is:
Complilation error. Exepected function or variable
The query is a query which joins 4 tables and pastes the fields into another table. When using a standard MS Access query it works fine. I then generated and copied the SQL code (below) but unfortunately cannot get the query to work.
A final note about something strange. Unlike all the other SQL queries i have successfully written, this one, upon writing the Application.DoCmd.RunSQL (st_sql) into VBA, the space between the "L" and the "(st_sql) for some reason gets truncated.. Strange, this doesnt happen for any other string in the Whole routine where i successfully have other append queries.
Below is the code:
st_sql = "INSERT INTO[tblContactReporting03]([ID Project],[tblProjManagementPhaseHierarchy],[tblProjManagementSubPhaseHierarchy],[ID_Event],[SubTask_Hierarchy],[Project],[Sub project],[Project_Phase],[Project_Sub_Phase],[ContactFullName],[Role_Type],[type],[Event],[Effective_date],[Commitment],[Sub_task_name],[Status],[Notes])" & _
"SELECT[tblProjectMasterList].[ID Project],[tblProjManagementPhase].[Hierarchy],[tblProjManagementSubPhase].[Hierarchy],[tblContactReporting02].[ID_Event],[tblContactReporting02].[SubTask_Hierarchy],[tblProjectMasterList].[Project],[tblProjectMasterList].[Sub project],[tblProjManagementPhase].[Project_Phase],[tblProjManagementSubPhase].[Project_Sub_Phase],[tblContactReporting02].[ContactFullName],[tblContactReporting02].[Role_Type],[tblContactReporting02].[type]," & _
"[tblContactReporting02].[Event], [tblContactReporting02].[Effective_date],[tblContactReporting02].[Commitment],[tblContactReporting02].[Sub_task_name],[tblContactReporting02].[Status],[tblContactReporting02].[Notes]" & _
"FROM[tblProjectMasterListINNER JOIN ([tblProjManagementPhase] INNER JOIN ([tblContactReporting02] INNER JOIN [tblProjManagementSubPhase] ON [tblContactReporting02].[ID_Project_Sub_Phase] = [tblProjManagementSubPhase].[ID_Project_Sub_Phase]) ON ([tblContactReporting02].[ID_Project_Phase] = [tblProjManagementPhase].[ID_Project_Phase]) AND ([tblProjManagementPhase].[ID_Project_Phase] = [tblProjManagementSubPhase].[ID_Project_Phase])) ON [tblProjectMasterList].[ID Project] = [tblProjManagementPhase].[ID_Project]" & _
"ORDER BY [tblProjectMasterList].[ID Project], [tblProjManagementPhase].[Hierarchy], [tblProjManagementSubPhase].[Hierarchy], [tblContactReporting02].[ID_Event], [tblContactReporting02].[SubTask_Hierarchy];" & _
Application.DoCmd.RunSQL(st_sql)
I'd recommend a Debug.Print st_sql before running so that you'll be able to debug the constructed SQL.
The error you're getting is because RunSQL is a sub, not a function, so you need to call it 1) without parentheses:
Application.DoCmd.RunSQL st_sql
or 2) preceed it with Call and use parentheses:
Call Application.DoCmd.RunSQL(st_sql)
You can use syntax 2 for functions that when you don't need to use their return value.

Parameterized field name

I was thinking if this will work:
Dim query As String = "UPDATE tblPiglets SET #to=#todate, CurrentLocation=#to" & _
" WHERE Week=#week AND SowOrder=#so AND PigletNumber=#pig"
But I caught Cannot update #to field lol
The #to is a variable in which I thought would work the same its value though its worth a try. Its value is dependent on a user input, so, is there any other way to do that?
Or this? (not sure if this will work though):
Dim to As String = "foo"
Dim query As String = "UPDATE tblPiglets SET " & to & "=#todate, CurrentLocation=#to" & _
" WHERE Week=#week AND SowOrder=#so AND PigletNumber=#pig"
It is always preferable to use parameters to insert user input into SQL code but parameters can only be used for values, not identifiers. Think of SQL parameters the same as parameters in a VB method. You can't use a method parameter to specify a property or method to use and you can't use a SQL parameter to specify a column or table.
You have no choice but to use string concatenation but doing so opens you up to SQL injection, so make absolutely sure that the user cannot insert arbitrary SQL code. If it's a column name then they should have to select it from a list that you have retrieved from the database itself, so that you are guaranteed that it's a valid column.
I have used option 2 to make it work.
Dim to As String = "foo"
Dim query As String = "UPDATE tblPiglets SET " & to & "=#todate, CurrentLocation=#to" & _
" WHERE Week=#week AND SowOrder=#so AND PigletNumber=#pig"
But it would be nicer if I can get the same result if I will be using the first option. thanks