 |
Fidel Beginner
Joined: 07 Oct 2009 Posts: 19 Location: Poland
|
Posted: Wed Jun 16, 2010 8:26 pm
[3.19e] Database query problem |
Hi,
After updating to 3.19e I have a problem with database queries. Every second query is not valid.
I'm using COM object to connect to Microsoft Access database file.
To create a connection I do the following:
Code: |
#VAR connection %comcreate("ADODB.Connection");
#VAR connection.ConnectionString "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Arkadia\Odmiana.mdb";
#CALL @connection.Open;
|
After that, I want to do a query in one table of this database using:
Code: |
#VAR resultSet @connection.Execute("SELECT Mianownik FROM Rzeczowniki WHERE Mianownik = 'Krasnolud'"); |
Every second query is not valid. I tried both to close and not result set.
Echoing @resultSet.EOF using #ECHO EOF: @resultSet.EOF shows (first resultSet is not valid, second is valid):
Code: |
EOF: <COMObject>.EOF
EOF: False
|
Can you help with this anyhow?
Thanks
Fidel
PS:
When I call #UNVAR on the variable it works fine
It looks like @resultSet.Close doesn't work as it should. |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Jun 16, 2010 11:00 pm |
I think this is related to the "[3.18b-3.19e]BUG: %comcreate issues" post above and will hopefully be fixed in the next update later today. When 3.19f is released, give it a try to see if this problem is fixed.
|
|
|
 |
Fidel Beginner
Joined: 07 Oct 2009 Posts: 19 Location: Poland
|
Posted: Thu Jun 17, 2010 7:46 pm |
After update I still have the same problem.
But I have found something that migth be helpful:
After calling
#CALL @resultSet.Close
When I use:
#VAR resultSetLicznik @connectionLicznik.Execute($queryStr);
The problem occures.
But when I call:
#VAR Licznik/ConnectionLicznik/resultSetLicznik @connectionLicznik.Execute($queryStr);
There is no such problem.
"Licznik" is a package and "ConnectionLicznik" is a class in which variable is defined.
I'm not sure if this is walkaround or it has to be done that way.
For me the problem is resolved using the method which I've described.
Thanks |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Jun 17, 2010 8:25 pm |
Where is the script that is using the
#VAR resultSetLicznik @connectionLicznik.Execute($queryStr)
command? Is it in the other package, or in a trigger within the session window, or what? Is the resultSetLicznik variable in a Module that is set to Global?
You need to give more details on your package setup for me to help more with this. |
|
|
 |
Fidel Beginner
Joined: 07 Oct 2009 Posts: 19 Location: Poland
|
Posted: Thu Jun 17, 2010 8:40 pm |
I have created new package "Licznik", which is Global
In this package I have created a trigger (without a class) which calls a function existsInDatabase(string) from class ConnectionLicznik (same package)
script: #VAR resultSetLicznik @connectionLicznik.Execute($queryStr) is used in mentioned function which body is:
Code: |
#CALL @resultSetLicznik.Close;
#VAR Licznik/ConnectionLicznik/resultSetLicznik @connectionLicznik.Execute($queryStr); |
SQL provided to the function is created this way:
Code: |
%concat("SELECT Ile FROM Licznik WHERE Kto = '", %1,"' AND Kogo = '", %2, "'") |
Connection and resultSet variables are in the same package and class (Licznik/ConnectionLicznik) where the function is defined.
Connection is established only once using onLoad event (from main package).
Write if you need any more details.
Thanks |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Jun 17, 2010 9:44 pm |
OK, I think it's an issue with trigger context that you need to understand.
When a trigger fires, the context (default class) is set to the WINDOW that received the text which caused the trigger to fire. When you use the #VAR command to create a new variable, the variable is created in this default "context" class. So the variable does not normally get created in the "Licznik/ConnectionLicznik/" package/module if it doesn't already exist.
To force a new variable to be created within the same class as the trigger itself, you can use #NEWVAR.
So, the next question is: If you remove the "Licznik/ConnectionLicznik/" from the beginning of the variable name, check to see where this variable is getting created. Remove any other variable within your package and allow CMUD to use your current Window context as the proper place to store the variable.
The reason it works this way is that you might have multiple windows sharing the same package, so you'd want each trigger within each different window to create a different @resultSetLicznik variable.
If you only want there to be a single @resultSetLicznik variable, then you can put it in your package but then you must reference it with the "Licznik/ConnectionLicznik" path as you mentioned above to ensure that the package can find this single variable no matter which window it is called from. |
|
|
 |
Fidel Beginner
Joined: 07 Oct 2009 Posts: 19 Location: Poland
|
Posted: Thu Jun 17, 2010 11:25 pm |
Thanks for this explanation it helps to understand that and should help in future :)
I have only one instance of variable resultSetLicznik, so I thought that I don't have to give full path (and it worked on earlier versions).
Thanks again |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Fri Jun 18, 2010 2:20 am |
Quote: |
(and it worked on earlier versions). |
OK, well that part *is* odd. If somebody could simplify this into a test script that I can reproduce in a blank session then I'll have a better chance to track it down. I can't think of anything that I changed in that part of the code, but if it's not finding the existing variable, that still sounds like a problem. |
|
|
 |
Fidel Beginner
Joined: 07 Oct 2009 Posts: 19 Location: Poland
|
Posted: Fri Jun 18, 2010 10:06 am |
Of course I can give you my script.
http://www.voila.pl/368/qi5qx/index.php?get=1&f=1
In this zip file, you can find mdb file and package Licznik.
To test this:
Create new empty package, for example "testLicznik"
Copy database file to this package folder
Add Licznik.pkg to the session
In Licznik/ConnectionLicznik/connectLicznik change path to file "Source=testLicznik\Licznik.mdb"
#CALL connectLicznik();
The script is used to count how many foes player has killed.
Calling #SH Zabiles ork. Adds 1 to your counter (JA = me).
Call it for exaple 3 times. Use alias "licznik", you will see the results.
After that change function queryLicznik so it uses #VAR resultSetLicznik instead of full path to variable.
Use #SH Zabiles ork.
Every second trigger call will not be valid: querying if in database is record JA, ork will fail. So he will insert new row instead of updating existing one.
use Alias licznik, you will see that there are multiple rows now, or you can open database and see it in the table.
I'm using Windows 7 and Microsoft Office 2007 prof.
You wrote, that
Quote: |
but if it's not finding the existing variable, that still sounds like a problem |
I don't think cmud has a problem with finding this variable. It looks more like every second time it creates not valid COMObject.
You can add #ECHO @resultSetLicznik.EOF in function insteniejeWBazieLicznik (eng: existsInDatabaseLicznik) after the query and before if.
Every second query it shows strange <COMObject>.EOF instead of True/False, so the COMObject seems to be corupted or different type.
Thanks |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Fri Jun 18, 2010 8:53 pm |
Sorry I'm not going to have a chance to look at this for the 3.20 version today. I'll try to look into this more next week.
|
|
|
 |
|
|