SQL Updates/Inserts with data with double quotes - sql-server-2008

I have a database that collects client information using assessments and other tools. Often in the assessments there are double quotes in the data when - as may be expected - a direct quote is captured. When I run sql updates (Access front end using VBA to SQL Server 2008 R2 backend) it blows up on double quotes in the data. In the interim I've asked staff to use single quotes when they enter data, but that is an unsustainable solution as they forget and the program crashes when it hits the double quotes. The datatype is nvarchar(max).
The current VBA string looks like this:
strInsertSQL = "INSERT INTO tblIRPDetail(IRPID, SectionID, Challenge, Goal, Objective, Intervention, IntDate) VALUES(" & intNewID & ", " & intSection & ", """ & strChallenge & """, """ & strGoal & """, """ & strObjective & """, """ & strIntervention & """, """ & strIntDate & """);"
Essentially any of the strVariables could have single or double quotes in any combination. It works for single quotes but not doubles. Surely this is a fairly common issue, I'm hoping someone has a simple solution!
Thanks in advance!

An Access SQL statement can use either single or double quotes for text values. So you could use single quotes in your INSERT statement, but then you would run into a similar problem when the text to insert includes single quotes and which you could then resolve by doubling up the single quotes within the insert text:
Replace(strChallenge, "'", "''")
That doesn't seem like much of an improvement. OTOH, since you're using VBA to insert a row to your table, you don't need to use an INSERT query.
Open your table as a DAO.Recordset, add a new row, then assign your variable values to the corresponding fields.
Public Sub NPO_AddRow()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("tblIRPDetail", dbOpenTable, dbAppendOnly)
With rs
.AddNew
!IRPID = intNewID
!SectionID = intSection
!Challenge = strChallenge
!Goal = strGoal
!Objective = strObjective
!Intervention = strIntervention
!IntDate = strIntDate
.Update
.Close
End With
Set rs = Nothing
Set db = Nothing
End Sub
Note that, unlike a parameter query, this approach will allow you to add text strings longer than 255 characters.

Parameterize you query and add the values as parameters instead.
This might help:
parameterized query in ms access 2003 using vba

give me a minute and ill copy over the methods i used to get this performed.
In the mean time why not do a Replace(val, """, "'")? That way any instance of a " in the string will be replaced with a single quote '?

Related

Query of concatenation on Access [duplicate]

Any help that can be provided to a Access and VB noob would be greatly appreciated. What I'm trying to do is concatenate the values from one table and insert it as a comma delimited value into a field in another table. I'm trying to take all the server names that are say Linux boxes and concatenate them into a different field.
Table A looks like this
Machine Name | Zone | Operating System
----------------------------------------
Server01 Zone A Linux
Server02 Zone B Linux
Server03 Zone A Windows
Server04 Zone C Windows
Server05 Zone B Solaris
Table B has the field I want to insert into: Affected_Machine_Names.
Now, I've tried looking through the Concatenate/Coalesce posts, but the SQL view in Access doesn't like the Declare statements. My VB skills suck badly and I can't seem to get the code to work in VB for Applications. Unfortunately, I can't get this database converted into our SQL farm cause I don't have a server available at the moment to host it.
Can anyone point me in the right direction?
You can use Concatenate values from related records by Allen Browne for this. Copy the function code from that web page and paste it into a new standard module. Save the module and give the module a name different from the function name; modConcatRelated would work.
Then I think you should be able to use the function in a query even though you're not proficient with VBA.
First notice I changed the field names in TableA to replace spaces with underscores. With that change, this query ...
SELECT
sub.Operating_System,
ConcatRelated("Machine_Name", "TableA",
"Operating_System = '" & sub.Operating_System & "'") AS Machines
FROM [SELECT DISTINCT Operating_System FROM TableA]. AS sub;
... produces this result set:
Operating_System Machines
Linux Server01, Server02
Solaris Server05
Windows Server03, Server04
If you can't rename the fields as I did, use a separate query to select the distinct operating systems.
SELECT DISTINCT TableA.[Operating System]
FROM TableA;
Save that as qryDistinctOperatingSystems, then use it in this version of the main query:
SELECT
sub.[Operating System],
ConcatRelated("[Machine Name]", "TableA",
"[Operating System] = '" & sub.[Operating System] & "'") AS Machines
FROM qryDistinctOperatingSystems AS sub;
This is a fairly basic VBA function that will loop through every row in a column, and concatenate it to a comma-delimited result string. i.e., for your example, it will return "Server01, Server02, Server03, Server04, Server05". (Don't forget to replace the column and table names)
Function ConcatColumn(OS As String) As String
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("Select * from TableA")
Dim result As String
'For every row after the first, add a comma and the field value:
While rst.EOF = False
If rst.Fields("Operating System") = OS Then _
result = result & ", " & rst.Fields("MyValue")
rst.MoveNext
Wend
'Clean it up a little and put out the result
If Left(result, 2) = ", " Then result = Right(result, Len(result) - 2)
Debug.Print result
ConcatColumn = result
End Function
To use this,
1. ConcatColumn("Windows") will return "Server04, Server03"
2. ConcatColumn("Linux") will return "Server01, Server02"
3. ConcatColumn("Solaris") will return "Server05"
4. ConcatColumn("") will return "".

Concatenate fields from one column in one table into a single, comma delimited value in another table

Any help that can be provided to a Access and VB noob would be greatly appreciated. What I'm trying to do is concatenate the values from one table and insert it as a comma delimited value into a field in another table. I'm trying to take all the server names that are say Linux boxes and concatenate them into a different field.
Table A looks like this
Machine Name | Zone | Operating System
----------------------------------------
Server01 Zone A Linux
Server02 Zone B Linux
Server03 Zone A Windows
Server04 Zone C Windows
Server05 Zone B Solaris
Table B has the field I want to insert into: Affected_Machine_Names.
Now, I've tried looking through the Concatenate/Coalesce posts, but the SQL view in Access doesn't like the Declare statements. My VB skills suck badly and I can't seem to get the code to work in VB for Applications. Unfortunately, I can't get this database converted into our SQL farm cause I don't have a server available at the moment to host it.
Can anyone point me in the right direction?
You can use Concatenate values from related records by Allen Browne for this. Copy the function code from that web page and paste it into a new standard module. Save the module and give the module a name different from the function name; modConcatRelated would work.
Then I think you should be able to use the function in a query even though you're not proficient with VBA.
First notice I changed the field names in TableA to replace spaces with underscores. With that change, this query ...
SELECT
sub.Operating_System,
ConcatRelated("Machine_Name", "TableA",
"Operating_System = '" & sub.Operating_System & "'") AS Machines
FROM [SELECT DISTINCT Operating_System FROM TableA]. AS sub;
... produces this result set:
Operating_System Machines
Linux Server01, Server02
Solaris Server05
Windows Server03, Server04
If you can't rename the fields as I did, use a separate query to select the distinct operating systems.
SELECT DISTINCT TableA.[Operating System]
FROM TableA;
Save that as qryDistinctOperatingSystems, then use it in this version of the main query:
SELECT
sub.[Operating System],
ConcatRelated("[Machine Name]", "TableA",
"[Operating System] = '" & sub.[Operating System] & "'") AS Machines
FROM qryDistinctOperatingSystems AS sub;
This is a fairly basic VBA function that will loop through every row in a column, and concatenate it to a comma-delimited result string. i.e., for your example, it will return "Server01, Server02, Server03, Server04, Server05". (Don't forget to replace the column and table names)
Function ConcatColumn(OS As String) As String
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("Select * from TableA")
Dim result As String
'For every row after the first, add a comma and the field value:
While rst.EOF = False
If rst.Fields("Operating System") = OS Then _
result = result & ", " & rst.Fields("MyValue")
rst.MoveNext
Wend
'Clean it up a little and put out the result
If Left(result, 2) = ", " Then result = Right(result, Len(result) - 2)
Debug.Print result
ConcatColumn = result
End Function
To use this,
1. ConcatColumn("Windows") will return "Server04, Server03"
2. ConcatColumn("Linux") will return "Server01, Server02"
3. ConcatColumn("Solaris") will return "Server05"
4. ConcatColumn("") will return "".

Why does this SQL work in one format, but not another?

I've been having this problem with MySQL for the past month. It's not a big problem, but it's pretty annoying.
query = "SELECT * FROM MESSAGE_TEMPLATES WHERE MESSAGE_SEND_DATE = '" & _date & "'"
This simple line works fine when I pass it to the dataReader in MySQL. However:
query = "SELECT * FROM MESSAGE_TEMPLATES" & _
" WHERE MESSAGE_SEND_DATE = '" & _date & "'"
This does not work, even though intellisense shows them both to have the same value. MySQL complains about having an error in the syntax. You can imagine this becomes more problematic for larger statements that take up several lines. What exactly am I missing here?
Can you print out each string to a console or a log and look for any random white space or involuntarily-included control characters?
It should work - can't be an MySQL thing as a strings a string. If it persists consider using XML syntax to allow you to do the multi-line thing:
Dim query = <sql><![CDATA[
SELECT * FROM MESSAGE_TEMPLATES
WHERE MESSAGE_SEND_DATE = :Date
]]></sql>.Value
Also note that you should be using parameterized queries as they are more secure easier to read and faster.

Run-time error '3061'. Too few parameters. Expected 1. (Access 2007)

I have the following 'set recordset' line that I cannot get working. The parameters seem correct according to all available help I can find on the subject.
The error displays :
"Run-time error '3061'. Too few parameters. Expected 1."
Here is the line of code:
Set rs = dbs.OpenRecordset("SELECT Centre_X, Centre_Y FROM [qry_all_details]
WHERE ID = " & siteID & ";", dbOpenSnapshot)
Where rs is the recordset (Dim rs As Recordset) and dbs = CurrentDb()
Any help would be appreciated.
I have tried removing the WHERE cause with no effect, and also using single quotes between double quotes, but no joy.
Many thanks.
"Run-time error '3061'. Too few parameters. Expected 1."
I believe this happens when the field name(s) in your sql query do not match the table field name(s), i.e. a field name in the query is wrong or perhaps the table is missing the field altogether.
you have:
WHERE ID = " & siteID & ";", dbOpenSnapshot)
you need:
WHERE ID = "'" & siteID & "';", dbOpenSnapshot)
Note the extra quotations ('). . . this kills me everytime
Edit: added missing double quote
(For those who read all answers). My case was simply the fact that I created a SQL expression using the format Forms!Table!Control. That format is Ok within a query, but DAO doesn't recognize it. I'm surprised that nobody commented this.
This doesn't work:
Dim rs As DAO.Recordset, strSQL As String
strSQL = "SELECT * FROM Table1 WHERE Name = Forms!Table!Control;"
Set rs = CurrentDb.OpenRecordset(strSQL)
This is Ok:
Dim rs As DAO.Recordset, strSQL, val As String
val = Forms!Table!Control
strSQL = "SELECT * FROM Table1 WHERE Name = '" & val & "';"
Set rs = CurrentDb.OpenRecordset(strSQL)
My problem was also solved by the Single Quotes around the variable name
I got the same error message before.
in my case, it was caused by type casting.
check if siteID is a string, if it is you must add simple quotes.
hope it will help you.
My problem turned out to be, I had altered a table to add a column called Char.
As this is a reserved word in MS Access it needed square brakcets (Single or double quote are no good) in order for the alter statement to work before I could then update the newly created column.
Make sure [qry_all_details] exists and is runnable. I suspect it or any query it uses, is missing the parameter.
I got the same error with something like:
Set rs = dbs.OpenRecordset _
( _
"SELECT Field1, Field2, FieldN " _
& "FROM Query1 " _
& "WHERE Query2.Field1 = """ & Value1 & """;" _
, dbOpenSnapshot _
)
I fixed the error by replacing "Query1" with "Query2"
In my case, I got this error when I tried to use in a query a new column, which I added to MySQL table (linked to MS Access), but didn't refresh it inside MS Access.
To refresh a linked remote table:
Open "Linked Table Manager" ("External Data" tab on ribbon);
Select a checkbox near the table you want to refresh;
Press "OK" button.
In my case I was receiving this error when running a query from VBA with this command:
CurrentDb.Execute "qryName"
Double clicking on the query to execute it, worked fine, no error.
Changing the code to the following also worked fine, no error.
DoCmd.OpenQuery "qryName"
Hope this helps someone else who is unexpectedly getting this error.
If someone could explain why the first command caused the error I'd love to know.
Does the query has more than the parameter siteID, becouse if you want to run the query one parameter still isn't filled witch gives you the error
In my case, I had simply changed the way I created a table and inadvertently changed the field name I tried to query. Make sure the field names you reference in the query actually exist in the table/query you are querying.
This Message is also possible to pop up, if there is a typo in the fields on which you define a join
Thanks for John Doe's solution that helped a lot. Mine is very similar with some difference, using TempVars
Instead of :
strSQL = "SELECT * FROM Table1 WHERE Name = Forms!Table!Control;"
I used:
strSQL = "SELECT * FROM Query1" , Query1 being common for other usage
Query1 as:
"Select Field1, Field2 from Table1 where Id= [TempVars]![MyVar]
And similarly, removing [TempVars]![MyVar] from view solved the problem.
In My case I had an INSERT INTO TableA (_ ,_ ,_) SELECT _ ,_ ,_ from TableB, a run-time error of 33061 was a field error. As #david mentioned. Either it was a field error: what I wrote in SQL statement as a column name did not match the column names in the actual access tables, for TableA or TableB.
I also have an error like #DATS but it was a run-time error 3464.

vbscript to export an access query to a tab delimited file not working

I have this code:
db = "C:\Dokumente und Einstellungen\hom\Anwendungsdaten\BayWotch4\Neuer Ordner\baywotch.db5"
TextExportFile = "C:\Dokumente und Einstellungen\hom\Anwendungsdaten\BayWotch4\Neuer Ordner\Exp.txt"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open _
"Provider = Microsoft.Jet.OLEDB.4.0; " & _
"Data Source =" & db
strSQL = "SELECT * FROM tblAuction1"
rs.Open strSQL, cn, 3, 3
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.CreateTextFile(TextExportFile, True)
a = rs.GetString
f.WriteLine a
f.Close
Which is meant to connect to an access database and produce a tab delimited text file. tblAuction1 is a query in the database, and definitly exists and is not misspelt in any way, but I get an error that it cannot be found or does not exist. When I change it to tblAuction which is the name of the table, I get an error stating f.WriteLine a has been called incorrectly.
edit: I now only get a problem with f.writeline a, saying an incorrect argument has been supplied. I no longer have a problem with tblAuction1
edit: the sql code used for my query:
SELECT tblAuction.article_no, tblAuction.article_name, tblAuction.subtitle, tblAuction.current_bid, tblAuction.start_price, tblAuction.bid_count, tblAuction.quant_total, tblAuction.quant_sold, tblAuction.start, tblAuction.ends, tblAuction.origin_end, tblUser.user_name, tblAuction.best_bidder_id, tblAuction.finished, tblAuction.watch, tblAuction.buyitnow_price, tblAuction.pic_url, tblAuction.private_auction, tblAuction.auction_type, tblAuction.insert_date, tblAuction.update_date, tblAuction.cat_1_id, tblAuction.cat_2_id, tblAuction.article_desc, tblAuction.countrycode, tblAuction.location, tblAuction.condition, tblAuction.revised, tblAuction.paypal_accept, tblAuction.pre_terminated, tblAuction.shipping_to, tblAuction.fee_insertion, tblAuction.fee_final, tblAuction.fee_listing, tblAuction.pic_xxl, tblAuction.pic_diashow, tblAuction.pic_count, tblAuction.item_site_id
FROM tblUser INNER JOIN tblAuction ON tblUser.id = tblAuction.seller_id;
I have tried to reproduce this on several databases and machines, I can't get your code to fail.
Leaves :
a corrupt database, could you please run repair and try again ?
Fields in your database that are throwing of the query, I have tried several possibilities but can't find anything that brakes your code. To exclude other things you could try to create a new table and see if your code works on that table.
something wrong with your dll's , could you try it on another machine.
Answer (to see how we came to the answer see the comments)
There are unicode characters in your database that writeline does not accept because you created the textfile as ASCI.The characters in this case specifically where ♥♥♥
To make it work:
Set f = fs.CreateTextFile(TextExportFile, True, True)
P.S.
This question was answered earlier using the transfertext macro here
As Remou points out this looks like a cleaner solution. To make it work with non-default delimiters is a bit of a pain. First start exporting the query you like to export by right clicking and choose export. In the following dialogs specify the specifications and save these. When creating the macro select the specifications you just saved.
I think there is something wrong with the spaces in your connection string
Try this:
cn.Provider = "Microsoft.Jet.OLEDB.4.0"
cn.ConnectionString = db
cn.Open
HTH
Update:
Maybe there is a problem with the access rights to the database?
Or the mdb is already opened exclusively by another user (You with your access in design mode)?
Try this
cn.Open _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Persist Security Info=False;" & _
"Data Source=" & db