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
Related
My old website in ASP started generating this error:
Microsoft Cursor Engine error '80040e21'
Multiple-step operation generated errors. Check each status value.
I haven't changed recently anything - perhaps my hosting provider made a change but the error is pointing to this line of code:
rs.Open SQL, adoCon
I checked: rs, adoCon and SQL are all set and it used to work for years before.
Set rs = Server.CreateObject("ADODB.Recordset")
adoCon.Open "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=<SERVER_NAME>; PORT=<PORT_NUMBER>;" &_
"DATABASE=<DBNAME>; USER=<USERNAME>; PASSWORD=<PASS>; OPTION=3;"
SQL is correct - I directly injected it into mySQL web interface and it generated needed results.
When I handle this error in ASP the Error.Description prints
"Object required"
What is it complaining about?
The answer to my question is that I had to convert decimal field to string. The fix looked like this:
SELECT Convert(Price,char) as Price FROM Table;
This is very strange but perhaps something was changed on my hosting provider site that caused this issue. I actually found similar solution here (strange mysql results in asp) which helped me to discover the issue. As I quote from link above "ASP can't recognize the results from MySQL and thinks it's EOF" without conversion from decimal to string.
For me it happened years ago With Oracle's Date/Time field having corrupt values causing this exact error when trying to select them.
Guess it's the same issue behind the scenes, what worked for me was manually deleting the corrupt rows using Oracle tools.
Another tip that has small chance to work is having such code instead:
adoCon.Open "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=<SERVER_NAME>; PORT=<PORT_NUMBER>;" &_
"DATABASE=<DBNAME>; USER=<USERNAME>; PASSWORD=<PASS>; OPTION=3;"
Set rs = adoCon.Execute(SQL)
Hopefully the cursor used in this method won't crash.
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.
We've just upgraded from Access 2003 to Access 2010 and string comparisons are failing with an invalid procedure call error when default conditions are used. I’ve recreated two presumably related problems in a new Access 2007 format database containing only the default table, a query with the SQL below and a module containing only the code below, so I seriously doubt that this is a corruption issue.
First the following sub fails on the If Then line with Run-time error 5: Invalid procedure call or argument
Option Compare Database
Option Explicit
Sub checkStrCmp()
Dim str As String
str = "s"
If str = "s" Then
MsgBox "works"
End If
End Sub
If I change Option Compare Database to Option Compare Text the sub works as expected, but this seems like a bad idea as I may want to preform text as well as numeric comparisons inside a single sub.
I’m also getting “Invalid procedure call” errors in string comparison functions inside of SQL. The Replace function is requiring the supposedly optional compare parameter.
Select replace("foo-bar-baz", "-", "|", 1,-1);
Generates the “Invalid procedure call” error
Setting the compare parameter to any of the available values (0 -3) works as expected:
SELECT replace("foo-bar-baz", "-", "|", 1,-1, 0);
produces “foo|bar|baz”
Has anyone else seen this? Is there a setting that needs to be tweaked? Any other ideas outside of “Database corruption” which is all I’ve been able to find via Google.
TIA
apoligies for the sloppy code blocks I can't for the life of me get them to work right.
UPDATE: I should have mentioned that I'm running XP Pro sp3.
The problem seems limited to databases I create on my box. When I opened the test database I created on my box from other workstations on our network I saw the issue, but was then unable to recreate it when creating a new database as described above on those workstations. The databases I created on the two other workstations (same OS and MS Office versions installed) also worked correctly when opened on my machine. I was also unable to recreate the issue when I inserted new modules in those DBs from my machine.
In short the problem seems to only exist on databases created on my machine (and in old 2003 format databases I've converted to 2007 format on my machine). My best guess is that my install is hosed but I’d like to have some idea of how and why before I approach IT with a request to reinstall Office. I’d also like to rule out a conflict with other software on my box.
Your code modules do not all need to share the same Option Compare setting. So you could place those procedures which should use text comparisons in a module which has Option Compare Text in its Declarations section.
However, I don't understand your statement, "I may want to preform text as well as numeric comparisons inside a single sub." According to Access' help topic, the Option Compare Statement is "Used at module level to declare the default comparison method to use when string data is compared". In other words, Option Compare has no effect on the comparisons of numeric values.
Edit: Since the problem is limited to Option Compare Database for database files created on only one machine, I'll suggest you check Access' "New database sort order" setting on that machine. Change it to a choice which starts with "General" if it is set to anything else. Then create a new database and see whether you still have the problem.
The reason for this suggestion is that Option Compare Database tells Access to use the database's codepage setting for sorting. And "New database sort order" can set the codepage to the one which never gives me such troubles. However, my understanding of codepage details is pretty shallow; I never change it and don't know what the consequences of other settings would be.
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]).
I have a problem that just started happening after I reinstalled my website's server.
In the past I could do do this:
Code:
<%
set msgSet = conn.execute("select * from base_scroller where scroller_num = 1"
%>
check if it's not empty or anything else
Code:
<% if msgSet("scroller_name") <> "" then %>
and if it is i could do anything with it (like showing it's value)
Code:
<%= msgSet("scroller_name") %>
<% end if %>
Now I can't do this, the "if" test doesn't work with the "msgSet("scroller_name")" and I have to redifine it first in another variable
Code:
<% scrollername = msgSet("scroller_name") %>
then and only then I can do tests on it...
Code:
<% if scrollername <> "" then %>
and show it too.
<%= scrollername %>
<% end if %>
I would just like to get back the option to do the operations on the mysql recordset variables like b4....
Has someone come across this problem ? what has changed, is it a falty mysql varsion or something ?
Thank you guys.
There are two things you should do to ensure you have a value in a field:
Make sure the recordset is not empty.
Make sure the field in the current does not have a NULL value.
I am not away of any changes in the drivers that have affected your code, but I assume the difference is that your string actually returns an empty string (which would equal "") and your recordset is returning a proper NULL value (which is not equal "")
More details:
my odbc is: mysql 5.1 driver.
my mysql version : mysql server 5.0
my connetion string is:
I've tried to remove the STMT=SET CHARACTER SET hebrew;OPTION=3; part - no change...
the problem is using any variables right from the db, it could be any kind of variable (text,date,int)...
even
day(msgSet("scroller_date")) doesn't work now...
and th funny this is... it all used to work just fine.. b4 the installation
you see anything out of the ordinary ? maybe a different mysql/ODBC version ?
Ok...
the new odbc is 5.1 : located on the mysql.com servers (link: http://dev.mysql.com/downloads/connector/odbc/5.1.html)
Yes. I've reinstalled the OS (windows server 2003) again on my webserver and installed mysql server 5.0 on it.
I'm not getting an error,it is just not returning any data when I use the method I was explaining abourt, and I have to use the extra variables like I explained.
Do you require anymore details please ?
It could be a better way to test to check to see if the recordset is empty in an alternative manner.
I generally use:
On Error Goto 0
set msgSet = conn.execute("select * from base_scroller where scroller_num = 1"
If msgSet.EOF = True And msgSet.BOF = True Then
Response.Write "Recordset cursor was at the beginning and end of file - empty set."
Response.End
End If
This might help some way towards debugging it.
Oh, and something that might be important. I can't remember what caused it, but sometimes I found that when referencing MySQL fields via a recordset, it was always lower case, regardless of what the fields are in the database definition or query.
If this doesn't cause your script to fail, maybe try finding out what has been returned by the recordset.
Dim i
For Each i In msgSet.Fields
Response.Write i & "=[" & msgSet.Fields(i) & "]<br />"
Next
Good luck
Never seen that problem before, nor am I sure why (more information on the error would be helpful) - but, as a relatively quick fix you may want to cast the item when you use it. Like:
<%= cStr(msgSet("scroller_name")) %>
See http://www.w3schools.com/vbscript/vbscript_ref_functions.asp#conversion for more information.
More information about the error you are getting would help you get a better answer. There is no MyODBC 5.1, so which version of the MyODBC drivers are you using? By "my odbc is: mysql 5.1 driver" you mean the driver for MySQL 5.1 - that should be MyODBC version 3.51.
Also, by "after I reinstalled my website's server" do you mean you did a clean install of the server OS? or did you just re-install MySQL? Or something else? MySQL 5.1 just came out 8 Dec. - was this part of an upgrade?
Lastly, please read some of the comments to your question and some of your replies. All things being equal, if there is some clarification needed, edit the question to add the details. Don't write a response. This isn't a forum, and you're response will lose its context the minute something is up-voted above it. Also its easier to take in the entire issue if its all in one spot as opposed to scrolling between the question and the various addendums posing as replies.
I'm getting the same problem...
Just migrating an asp site from mysql 4 & odbc 3.x (an old version...) to mysql 5.1 and odbc 5.1 .
If i try this simple code :
set rs = conn.execute("select ....")
while not rs.eof
response.write "t1 : " & rs("text") & "t2 : " & rs("text") & ""
rs.movenext
wend
as output i get the following :
t1 : hello
t2 :
t1 : how are you
t2 :
etc...
The second time I access the field it has no value, the only way is to use a temp variable to store the data the first time...