In MS Access assigning a string literal will sometimes result in an empty String
The following code
Public Sub test()
Dim myString As String
myString = "UPDATE "
Debug.Print "'" & myString & "'"
End Sub
results in
''
this is freaking me out. It only happens sometimes. Other times the "UPDATE " will work, but myString = "tblCategorie" won't. It needs to be exactly that String. If "UPDATE " fails, then "update " will still be okay.
I'm using MS Access 2003 11.8204.8221 SP3 Does anyone have the same problem?
(before you say: dump access! we're already doing that, but still in a transitional phase. I'm not really expecting anyone to come up with a decent answer, but a guy can hope)
[UPDATE]: Thanks for all the comments! let me just put really clear though that
it's not a typo. The same code sometimes works, and sometimes doesn't.
It's run in isolation so it's no global variable problem.
I have updated the sample to be the exact code that fails/doesn't fail. It's a literal copy. I test it by pasting it in a module and typing 'test' in the direct screen.
It first popped up in code that had worked flawlessly the past half year,
It is really the string assignment that fails (I can check that by putting a break on the assignment statement)
I generate my database from text exports, so it can't really be a corruption problem. (It could be, but it's not one that I can fix by compressing etc.)
Are you using On Error Resume Next i.e. is the assignment failing silently? That said, I can't think why an assignment of a String literal to a String variable would fail, which begs the question: is mySting really typed as String?
UPDATE: I see from your UPDATE (pun intended?) that my guesses are off. I simply cannot see how your code could fail to print anything other than 'UPDATE '. Perhaps you should now view this as an opportunity to abandon dynamic SQL in favour of prepared statements or, preferably, PROCEDURES (sure, in ACE/Jet's stored procs are limited to a single SQL statement but at least they keep the SQL code in the correct place i.e. the db).
Is the code you posted a copy of the code that is failing, or a reasonable facimile? I'm wondering if someting was lost in paraphrasing, as I don't see anything at all wrong with the code you posted.
Just a blind guess... are you sure you are typing the second "myString" correctly?
Beacuse il you don't (ex.
Debug.print "'" & mySting & "'"
) Access won't complain but it will create an empty variable...
Dump access! :-)
Something is FUBAR.Have you tried a Compact and Repair on the database?
The other thing I would try is to run a copile on the VBA code (Debug->Compile Access[X]).
Related
Good day, I'm having a problem updating records in MySQL. The following code is in VB.Net. Whenever I execute the code I get no errors, but the information is not saved in the table. Please tell me what I am doing wrong.
SQLstr = "UPDATE mainfinancials SET charge1=?charge1, charge2=?charge2, charge3=?charge3, charge4=?charge4, charge5=?charge5" _
& " WHERE acct='?acct';"
Pcomm.CommandText = SQLstr
If IsNumeric(txtCharge1.Text) Then Pcomm.Parameters.AddWithValue("?charge1", CDbl(txtCharge1.Text))
If IsNumeric(txtCharge2.Text) Then Pcomm.Parameters.AddWithValue("?charge2", CDbl(txtCharge2.Text))
If IsNumeric(txtCharge3.Text) Then Pcomm.Parameters.AddWithValue("?charge3", CDbl(txtCharge3.Text))
If IsNumeric(txtCharge4.Text) Then Pcomm.Parameters.AddWithValue("?charge4", CDbl(txtCharge4.Text))
If IsNumeric(txtCharge5.Text) Then Pcomm.Parameters.AddWithValue("?charge5", CDbl(txtCharge5.Text))
Pcomm.Parameters.AddWithValue("?acct", txtAcct.Text)
MsgBox(SQLstr)
Try
PConn.Open()
Pcomm.ExecuteNonQuery()
PConn.Close()
PConn.Dispose()
Catch ex As MySqlException
MsgBox(ex.Message.ToString())
PConn.Close()
End Try
I have deliberately place error in the the code and it would return an error message.
can some one help me with this.
Thanks
Do not enclose a parameter placeholder with single quotes
" WHERE acct=?acct;"
Enclosing the parameter placeholder in single quotes trasform its name in a literal value. So you query is searching a record where the acct column contains the literal value '?acct'.
Of course it finds nothing and nothing is updated
By the way, once a parameter placeholder is present in the query string, you should supply a parameter for it. If you forget to add the parameter an error occurs when you execute the command stating that an expected parameter is missing.
You place a test for IsNumeric and only if it succeds you add the parameter. I think you should test this error condition before and abort the update if something is not correct in your charge parameters.
A little while ago, in a peaceful world of happy programmers, ASP classic and MySQL (5.0) used to get along fine. ODBC (3.51) was their friend and data would flow from the heavens (read: database) without any issues.
Then, one day, a dark and mysterious event occurred. And now certain DataTypes within the MySQL Clan refuse to behave.
All of a sudden, TEXT stopped being available in the ASP object more than ONCE. Therefore any pre-test of NOT NULL became the end of the data in the object.
... Seriously. What the. You can see representations here: http://bugs.mysql.com/bug.php?id=44831 and here: http://forums.mysql.com/read.php?132,220948,220948
My question is: Has anyone found out why this has started happening. I have ZERO desire to go back and edit 100's of sites to put the value into a var immediately after the recordset is filled.
Halp me superman!
We've tried upgrading to MySQL 5.6 and ODBC 5.1.sumthin & 5.2.5... but nothing helped. (We did decide that the ODBC version had no impact on the issue)
Current production server remains at ODBC 3.51 + MySQL 5.0
Current test server comprises of ODBC 5.2.5 + MySQL 5.6
Edit: Using ADODB Connection
ie:
dim oC, oRs
set oC = Server.createObject("ADODB.Connection")
oC.Open database
set oRs = oC.execute("SELECT 'garble garble garble garble' as `textthing`;")
if not oRs.eof then
for x = 0 to 3
response.write "Output: "
response.write oRs("textthing") &"<br />"
next
end if
oRs.close
set oRs = nothing
oC.close
set oC = nothing
This results in:
Output: garble garble garble garble
Output:
Output:
Output:
(I'd ask for some latitude here: the above text string -> remember it's coming out as a TEXT or MEDIUMTEXT for the sake of this exercise.)
Edit 2:
(As noted in a comment below)
The working solution we have is this:
Change things that really don't need to be ***TEXT to VARCHAR(BigEnough).
And edit the ASP for things that need to be ***TEXT to put the value
straight into a variable.
This is far from being a great solution, however it does force you to consider your data more accurately - which can only be a good thing... right?
Mark, I'm taking a long shot here. For what I know of Classical ASP (which consists in years of swearing and loving), a NULL answer from the MySQL database results in... nothing, actually. Unless you define the recordset result as a string, it won't be comparable with a "". So, either you do this:
var recordsetVal = oRs("textthing")&""
... or you could simply do this:
if oRs("textthing")&"" <> "" then
Also, instead of while ... wend, use a do while...loop lace. It might work.
Again, this is a long shot. many factors could be involved in this question, but MySQL Driver and ODBC compatibility issue is only one of them and, fortunately, the least probable. Keep us posted.
I'm working on a Classic ASP (VBScript) site that's running on a Windows 2008 server with IIS7 and hitting a SQL Server 2008 database and I'm seeing some strange behavior that seems to be specific to fields that are of type nvarchar(max).
I have this simple bit of code that loops over some query results and tries to print out the title field twice
rs.open "SELECT * FROM thing", dbConnection
do while not rs.eof
response.write "(" & rs("title") & ")" & "(" & rs("title") & ")" & "<br />"
rs.movenext
loop
The first time I use rs("title"), I get the value back. Any time after the first time in that loop, rs("title") returns a blank value.
Again, this only seems to happen with the nvarchar(max) fields.
Can anyone shed any light on this behavior and how to get around it?
Very old thread - admitted. But I had this issue and it was driving me INSANE.
I fixed this by changing my connection string like this:
objConn.Open "Driver={SQL Server}; Server=(local); Database=<what-your-database-is-called>; Uid=sa;Pwd=sa;"
to:
objConn.Open "Provider=SQLNCLI; Server=(local); Database=<what-your-database-is-called> ; Uid=sa;Pwd=sa;"
So, essentially, removing Driver={SQL Server}
and adding in "Provider=SQLNCLI;", FIXED THIS.
I can now see the nvarchar(max) column displayed correctly in my Classic ASP page.
Hope this helps someone.
aside from the 'pull it into a variable before display'... I vaguely remember coworkers needing some hack with asp/sql/varchar(max) queries, something like it had to be the last column (or not the last column) in the query. Really sorry for the vagueness, it's been a few years since I've had to deal with asp.
If you take a look at this link, http://msdn2.microsoft.com/en-us/library/ms130978.aspx it says to enable SQL Server Native Client to get the latest features such as varchar(max) which was was introduced in SQL2005, so I think maybe using this would work for you as well even though you're using SQL 2008.
I did cast(columName to varchar) and it worked for me.
Not sure that this is the cause, but one thing worth noting is that the varchar(max) type was not added to Sql Server until well after the last version of Classic ASP was released. So it's very possible that the old ado provider just doesn't know how to deal with those fields.
I just had a similar problem (only with SQL Server 2005, not 2008):
If Not IsNull(rs("Title")) Then
Response.Write "The title: " & rs("Title")
End If
The Response.Write was executed, but the title itself was not displayed.
It took me quite some time until I figured out that the combination of ASP Classic and nvarchar(max) was causing the problem.
Then I found this and did what was described there...I changed my code to this:
SomeVariable = rs("Title")
If Not IsNull(SomeVariable) Then
Response.Write "The title: " & SomeVariable
End If
This issue remains or resurfaces with using DSN's on Server 2012 and 2016.
Using DSN send the data thru an immediate layer that appears to handle varbinary(max) fine but not varchar(max) or nvarchar(max).
It is a bit worst, because over time if you have actual results over 9K (in my case, one that was 400K), there appears to be corruption of memory/code and the server errors with a vague external component error
I have an Access 2003 database with some visual basic code using ADO calls in it. When I do a
strsql0 = "SELECT lnk_stockitm.C_C FROM lnk_stockitm WHERE (((lnk_stockitm.C_C) Like 'T*'));"
newRS.Open strsql0, cn1, adOpenKeyset, adLockReadOnly
newRS.movelast
I get this error:
3021 either bof or eof is true or the current record has been deleted
When I run the exact same query in the same function without the WHERE clause, like this:
strsql0 = "SELECT lnk_stockitm.C_C FROM lnk_stockitm;
I get the correct result of 56,000 records. If I paste the full SQL statement with the WHERE clause into a regular query, like so:
SELECT lnk_stockitm.C_C FROM lnk_stockitm WHERE (((lnk_stockitm.C_C) Like 'T*'));
it returns the correct subset of the results (2800 records).
Can anyone tell me what I am doing wrong?
The wildcard difference is the cause for difference between what you execute from ADO and within your access database. Convert your statement to use "%" rather than "*". As a general rule of thumb, it may be a good idea to encapsulate your code by checking for eof before calling MoveLast. If your query has zero results it'll bomb out every time.
strsql0 = "SELECT lnk_stockitm.C_C FROM lnk_stockitm WHERE (((lnk_stockitm.C_C) Like 'T*'));"
newRS.Open strsql0, cn1, adOpenKeyset, adLockReadOnly
if not newRs.eof then
newRS.movelast
else
' do something here if necessary to handle blank results
end if
You need to use the '%' character as wildcard when using ADO.
MSDN Article: Using the Right Wildcard Characters in SQL Statements
I have the following MySqlCommand:
Dim cmd As New MySqlCommand
cmd.CommandText = "REPLACE INTO `customer` VALUES( ?customerID, ?firstName, ?lastName)"
With cmd.Parameters
.AddWithValue("?customerID", m_CustomerID)
.AddWithValue("?firstName", m_FirstName)
.AddWithValue("?lastName", m_LastName)
End With
I have a class that handles execution of MySqlCommands and I'd like to have it log every query to a file. I can retrieve the query/command being executed with:
cmd.CommandText
but that just returns the original CommandText with the parameters (?customerID, ?firstName, etc.) and not the actual substituted values added by the AddWithValue functions. How can I find out the actual "final" query that was executed?
I did the following:
dim tmpstring as string = MySqlCommand.CommandText
For each p as MySqlParameter in MySqlCommand.parameters
tmpstring = tmpstring.replace(p.ParameterName, p.Value)
Next
This seems to output everything you need
I havn't seen a method for this.
And in any case, prepared statements are sent to the server with the ?customerID,?firstname parameters, and then the actual parameters are sent seperately - the mysql driver doesn't build up a final sql query like you'd do if you didn't use prepared statements.
The parameterised method you're using should be okay for preventing SQL injection.
.AddWithValue("?customerID", m_CustomerID)
If m_CustomerID contains the text
Haha I'm stealing your data; drop table whatever;
Then it won't end up being executed on the server as such. The AddWithValue sorts that out for you.
As for the actual executed query, you should be able to get that from the query-log, if it's enabled.
You would have to build it yourself.
Parameters are not just plopped into a string and then run as a SQL statement. The RDBMS will actually prepare the SQL and then use the parameter values as needed. Therefore, there's not a single SQL statement going to the server. To see what the SQL would be, you would have to do:
Console.WriteLine("REPLACE INTO `customer` VALUES('" & m_CustomerID & _
"', '" & m_FirstName & "', '" & m_LastName & "')")
I have the same need.
From what I've read, the query text isn't combined with the param values in the client - they are sent to the server for that.
To inspect what query was actually being sent to the server, I used mysqld logging. For my version of MySQL, I added this entry to the my.cnf:
log=queries.txt
Then, I was able to see clearly the effect of combining command text with parameters: in my case, after restarting the mysqld, I ran my unit tests and then opened the queries.txt file.
HTH!
If you want to manage logging yourself from the .NET application, your best bet is to continue using the MySqlCommand class with parameters to avoid SQL injection; however, when you log the CommandText, loop through the Parameters collection and log each one by name/type/value.