View previous topic :: View next topic |
Author |
Message |
Pyridon
Joined: 07 Oct 2005 Posts: 9
|
Posted: Fri Oct 07, 2005 19:39 Post subject: SQLExecDirect & INSERT INTO not working |
|
|
Okay, I am an NWNX noob, not so noob what comes to NWN scripting and databases. I am using SQLite and I made my own player data table and tried to insert into it, but that didn't succeed, and I don't know why. I tried the SQL scripts in SQLite command line client and they worked okay, but not from my module script.
Here's the table creation command:
Code: |
CREATE TABLE pcdata(
pcid INTEGER PRIMARY KEY AUTOINCREMENT,
pubcdkey char(8) NOT NULL,
playername varchar(64) NOT NULL,
pcname varchar(64) NOT NULL,
nvisits int(5) DEFAULT 1,
lastlogin timestamp(14) DEFAULT NULL
);
|
And here's the function. It is called from OnClientEnter:
Code: |
int InitPC(object oPC) {
string pubcdkey = GetPCPublicCDKey(oPC);
string playername = GetPCPlayerName(oPC);
string pcname = GetName(oPC);
int pcid = 0;
SQLExecDirect("SELECT pcid FROM pcdata WHERE pubcdkey='" + pubcdkey +
"' AND pcname='" + pcname + "';");
WriteTimestampedLogEntry("Looking for PC: " + pcname);
if (SQLFetch() == SQL_ERROR) {
// Not found, so create a new character entry into pcdata
WriteTimestampedLogEntry("Creating new PC: " + pcname);
SQLExecDirect("INSERT INTO pcdata (pubcdkey, playername, pcname,lastlogin) VALUES('" +
pubcdkey + "', '" + playername + "', '" + pcname + "', CURRENT_TIMESTAMP");
// Retrieve the pcid again
SQLExecDirect("SELECT pcid FROM pcdata WHERE pubcdkey='" + pubcdkey +
"' AND pcname='" + pcname + "';");
SQLFetch();
WriteTimestampedLogEntry("Created");
}
if (SQLFetch() == SQL_SUCCESS) {
// Character was found
WriteTimestampedLogEntry("Found PC: " + pcname);
pcid = StringToInt(SQLGetData(1));
SQLExecDirect("UPDATE pcdata SET nvisits = nvisits + 1, lastlogin = CURRENT_TIMESTAMP WHERE pcid=" + IntToString(pcid));
SQLFetch(); // I tried also without this SQLFetch
WriteTimestampedLogEntry("PCID=" + IntToString(pcid));
}
WriteTimestampedLogEntry("Returning PCID " + IntToString(pcid));
return pcid;
}
|
And finally, the relevant server log:
[Thu Oct 06 23:10:47] Pyridon (XXXXXXXX) Joined as Player 1
[Thu Oct 06 23:10:59] Looking for PC: Fallon Woods
[Thu Oct 06 23:10:59] Creating new PC: Fallon Woods
[Thu Oct 06 23:10:59] Created
[Thu Oct 06 23:10:59] Returning PCID 0
[Thu Oct 06 23:11:18] Pyridon Left as a Player (0 players left)
[Thu Oct 06 23:11:38] Server Shutting Down
After running this, the pcdata table is still empty. |
|
Back to top |
|
|
Pyridon
Joined: 07 Oct 2005 Posts: 9
|
Posted: Sat Oct 08, 2005 10:07 Post subject: |
|
|
Gee, I found nwnx logfile. It states this:
o Got request: SELECT pcid FROM pcdata WHERE pubcdkey='XXXXXXXX' AND pcname='Fallon Woods';
! SQL Error: malformed database schema - near "AUTOINCREMENT": syntax error
o Sent response (0 bytes):
Now why does nwnx complain of this ? The schema is okay, like I said... I can do inserts outside NWN just fine. |
|
Back to top |
|
|
Acrodania
Joined: 02 Jan 2005 Posts: 208
|
Posted: Sat Oct 08, 2005 23:42 Post subject: |
|
|
You have 6 columns in your database, your SQL statement only has 4 of them.....
With your INSERT statement you must account for all columns.
You are getting THAT error because when the insert runs you are trying to put the public CDKey in column one. The CDKey is alpha-numeric; autoincrement can only work with integers.....
You also don't physically put the trailing ; in the SQL string, NWNX will add it for you automatically when it runs. By putting that in you are cutting your SQL string off at that point as NWScript views it as its own end.... |
|
Back to top |
|
|
Pyridon
Joined: 07 Oct 2005 Posts: 9
|
Posted: Sun Oct 09, 2005 0:29 Post subject: |
|
|
Acrodania wrote: | You have 6 columns in your database, your SQL statement only has 4 of them.....
With your INSERT statement you must account for all columns.
|
Do you mean NWNX does not support the fields listing ?
The sql phrase
Code: |
INSERT INTO pcdata (pubcdkey, playername, pcname,lastlogin) VALUES('pubcdkey', 'playername', 'pcname', CURRENT_TIMESTAMP");
|
in itself is valid SQL statement, as I list the assigned fields and the AUTOINCREMENT field gets assigned automatically (how could I even assign a value to an autoincrement field?) and so does the nvisits as it defaults to 1. Like I said, I tested it in SQLite itself and it worked okay.
Like it says in the ODBC log, it already fails at the SELECT phrase so it never gets as far as trying the insertion, so I don't think this is the issue.
I did a second version of the database, leaving the PRIMARY KEY AUTOINCREMENT off, inserted a record by hand, and now at least the select phrase finds the entry. |
|
Back to top |
|
|
Acrodania
Joined: 02 Jan 2005 Posts: 208
|
Posted: Sun Oct 09, 2005 1:11 Post subject: |
|
|
It is a valid statement, but NOT for the table you listed!!!!
Quote: |
INSERT INTO pcdata (pubcdkey, playername, pcname,lastlogin) VALUES('pubcdkey', 'playername', 'pcname', CURRENT_TIMESTAMP");
|
should be something like
Quote: |
INSERT INTO pcdata (pcid,pubcdkey, playername, pcname,nvisits,lastlogin) VALUES('','pubcdkey', 'playername', 'pcname','1', NOW()");
|
You MUST have ALL fields listed in your insert statement or it WILL fail under MySQL. For those that AUTOINCREMENT you pass an empty value to it.
Fix one, THEN see how the other turns out You failed read is most likely because you have invalid data in your pcid field.
DO NOT compare how MySQL works compared to SQLite. SQLite allows ANY value, alpha or numeric, in any field. MySQL is much more picky and requires that fields and data be compatible. You can define a field in SQLite as integer and still put an alpha character into it. MySQL will bitch about it. |
|
Back to top |
|
|
Gryphyn
Joined: 20 Jan 2005 Posts: 431
|
Posted: Sun Oct 09, 2005 8:39 Post subject: |
|
|
Your not terminating your values (...)
You need
Code: | SQLExecDirect("INSERT INTO pcdata (pubcdkey, playername, pcname,lastlogin) VALUES('" +
pubcdkey + "', '" + playername + "', '" + pcname + "', CURRENT_TIMESTAMP)"); |
Note the closing bracket after TIMESTAMP, but within the quotes.
Cheers
Gryphyn
PS. You don't need to match table column counts. As long as the into's match the value's - AND the remaining fields have defaults (or Nulls are allowed) |
|
Back to top |
|
|
Pyridon
Joined: 07 Oct 2005 Posts: 9
|
Posted: Sun Oct 09, 2005 20:55 Post subject: |
|
|
Acrodania wrote: | It is a valid statement, but NOT for the table you listed!!!!
|
First, I don't understand why you speak of MySQL, as I stated I am using SQLite, not MySQL.
Second, I'm sorry, but it is a valid SQL statement even in the table I listed. This is a well documented SQL feature, and it also exists in MySQL and SQLite. If you don't believe me, check for example this page:
http://dev.mysql.com/doc/mysql/en/example-auto-increment.html
It features several valid insert statements where not all column values are explicitly set. If you need more proof, you can consult MySQL insert syntax, http://dev.mysql.com/doc/mysql/en/insert.html .
Even the purpose of autoincrement field is the very thing: the database takes care of automatically incementing that field, it is NOT supposed to be updated manually.
Now, it COULD be that NWNX ODBC does not support other than full field assignments. It seems more likely though, that it just does not approve using AUTOINCREMENT at all in a table, as it always complains: "SQL Error: malformed database schema - near "AUTOINCREMENT": syntax error". This happens always at the first attempt to perform any sql query on the table.
I've tested this, as I removed eveything except the first SELECT query, and it still fails. So, no insertion of any kind takes place and it still crashes. I made another version of the table, without autoincrement, and it performs okay. That is, the same SELECT query I mentioned before. I haven't yet tried to do any inserts from NWN as I have to overcome not being able to use the autoincrement and get the next free pcid manually.
And Gryphyn, thanks for pointing out the missing bracket.
Now I just have to overcome missing the autoincrement feature. I can do that, but it requires some extra effort... |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Sun Oct 09, 2005 22:41 Post subject: |
|
|
NWNX ODBC2 does nothing special to the SQL string. If it works in whatever program you use but not in NWN, there might be a version mismatch. _________________ Papillon |
|
Back to top |
|
|
Acrodania
Joined: 02 Jan 2005 Posts: 208
|
Posted: Mon Oct 10, 2005 1:20 Post subject: |
|
|
Pyridon wrote: | Acrodania wrote: | It is a valid statement, but NOT for the table you listed!!!!
|
First, I don't understand why you speak of MySQL, as I stated I am using SQLite, not MySQL.
Second, I'm sorry, but it is a valid SQL statement even in the table I listed. This is a well documented SQL feature, and it also exists in MySQL and SQLite. If you don't believe me, check for example this page:
http://dev.mysql.com/doc/mysql/en/example-auto-increment.html
It features several valid insert statements where not all column values are explicitly set. If you need more proof, you can consult MySQL insert syntax, http://dev.mysql.com/doc/mysql/en/insert.html .
Even the purpose of autoincrement field is the very thing: the database takes care of automatically incementing that field, it is NOT supposed to be updated manually.
Now, it COULD be that NWNX ODBC does not support other than full field assignments. It seems more likely though, that it just does not approve using AUTOINCREMENT at all in a table, as it always complains: "SQL Error: malformed database schema - near "AUTOINCREMENT": syntax error". This happens always at the first attempt to perform any sql query on the table.
I've tested this, as I removed eveything except the first SELECT query, and it still fails. So, no insertion of any kind takes place and it still crashes. I made another version of the table, without autoincrement, and it performs okay. That is, the same SELECT query I mentioned before. I haven't yet tried to do any inserts from NWN as I have to overcome not being able to use the autoincrement and get the next free pcid manually.
And Gryphyn, thanks for pointing out the missing bracket.
Now I just have to overcome missing the autoincrement feature. I can do that, but it requires some extra effort... |
Sorry I mis-interpreted the comment you made against testing it on SQLite for meaning that it worked there and not on MySQL I apologize for being an airhead...
As far as the set fields, I'm running from experience. I know what the docs say, but every time I've seen inserts setup with MySQL (up to version 4.1, I haven't used higher) they have failed if all fields weren't accounted for, EVEN when default values were setup on the tables. Under two different client programs, under both PHP3 and PHP4 and under NWN via Direct Connect.
If your mileage has been different I'm happy to hear it, but I always make sure they are specifically listed because of past issues. I haven't used SQLite enough to see how it handles things like that. |
|
Back to top |
|
|
Gryphyn
Joined: 20 Jan 2005 Posts: 431
|
Posted: Mon Oct 10, 2005 5:21 Post subject: |
|
|
Pyridon wrote: | Now, it COULD be that NWNX ODBC does not support other than full field assignments. It seems more likely though, that it just does not approve using AUTOINCREMENT at all in a table, as it always complains: "SQL Error: malformed database schema - near "AUTOINCREMENT": syntax error". This happens always at the first attempt to perform any sql query on the table. |
My understanding is the SQLite is embed into NWNX2 - That is NWNX2 manages everything.
There is a database name option on the CREATE TABLE that you might be needing (the schema id) eg CREATE TABLE database.pwdata
At a guess this would be the 'external' SQLite database/file you are using.
It may also be the SQLite version <3 AUTOINC = 32bits, 3+ 64bits {but that souldnt be and issue with Int->Str->Int (NWNX2)
http://www.sqlite.org/autoinc.html
Cheers
Gryphyn |
|
Back to top |
|
|
Lokey
Joined: 02 Jan 2005 Posts: 158
|
Posted: Mon Oct 10, 2005 13:20 Post subject: |
|
|
Acrodania wrote: | You MUST have ALL fields listed in your insert statement or it WILL fail under MySQL. For those that AUTOINCREMENT you pass an empty value to it. |
Haven't had this problem with NWNx from 2.5 years ago and MySQL 3.5ish when we first set things up. We don't create tables on the fly and our tables have default values and so on (and an auto-incremented field is never a key), so I'm not sure where the snag is that you hit.
gl Pyridon _________________ Neversummer PW NWNx powered mayhem |
|
Back to top |
|
|
odenien
Joined: 26 Sep 2005 Posts: 37
|
Posted: Mon Oct 10, 2005 13:23 Post subject: |
|
|
If you guys are still talking about the insert statement, Gryphyn was correct, it is not valid. Insert statements have to have both the column list and the data list surrounded by parentheis. Auto increment, if a database supports it is not added the insert list, nor is the data.
Normally, what I do is add a DebugPrint right before each sql statement that prints out to the logs. If something does not work, I will copy the statement to ODBCTest on windows and run the same statement. |
|
Back to top |
|
|
monezz
Joined: 03 Jan 2005 Posts: 52 Location: The Netherlands
|
Posted: Mon Oct 10, 2005 15:44 Post subject: |
|
|
The column list is optional if you provide all values.
example:
create table test (id int primary key auto_increment, value int);
valid insert statement:
insert into test values (1,1);
insert into test values (null,2); -- null will be replaced by the auto_increment value
insert into test (id,value) values (3,3);
insert into test (value) values (4); -- id will get the value from auto_increment |
|
Back to top |
|
|
odenien
Joined: 26 Sep 2005 Posts: 37
|
Posted: Tue Oct 11, 2005 13:46 Post subject: |
|
|
One other thing to note, if you do supply a column list, all NOT NULL columns without defaults must be supplied. Sort of obvious if you do this for a living, but not to everyone. |
|
Back to top |
|
|
Pyridon
Joined: 07 Oct 2005 Posts: 9
|
Posted: Tue Oct 11, 2005 23:49 Post subject: |
|
|
Papillon wrote: | NWNX ODBC2 does nothing special to the SQL string. If it works in whatever program you use but not in NWN, there might be a version mismatch. |
This isn't about the SQL string. It does not matter. Whatever I attempt at the SQLITE3 table defined like this:
Code: |
sqlite> .schema pcdata
CREATE TABLE pcdata(
pcid INTEGER PRIMARY KEY AUTOINCREMENT,
pubcdkey varchar(8) NOT NULL,
playername varchar(64) NOT NULL,
pcname varchar(64) NOT NULL,
nvisits int(5) DEFAULT 1,
lastlogin timestamp(14) DEFAULT NULL
);
|
produces log like this:
Code: |
o Logfile maximum size limit is: 524288 bytes
o Log level: Everything will be logged.
o Using SQLite connection.
o Hooking SCO....hooked at 5c65d0
o Hooking RCO....hooked at 5c64b0
o Connect successful.
o Got request: SELECT pcid FROM pcdata WHERE pubcdkey='XXXXXXXX' AND pcname='Fallon Woods';
! SQL Error: malformed database schema - near "AUTOINCREMENT": syntax error
o Sent response (0 bytes):
o Disconnecting from database.
|
As you can see, the table is quite valid in SQLite3, as the first output is directly from dumping a schema of an existing table. Doesn't the SQL query look quite correct too ?
When I run the SQL in SQLite client, it provides the following
Code: |
sqlite> SELECT pcid FROM pcdata WHERE pubcdkey='XXXXXXXX' AND pcname='Fallon Woods';
1
sqlite>
|
Then, now, why does the same select from NWNX crash ? The only reason I can think of, is that the current NWNX ODBC does not understand an SQL schema like described above. So, this may well be a version mismatch.
I am running latest NWN update (v1.66), NWNX2 version 2.6.1, NWNX ODBC2 v.0.9.2.4 and SQLite3 client (which I also used to create the table schema) is version 3.2.7.
The trouble is, how to correct that version mismatch ? I'd hate to create the table from NWN via SQLDirect as it is a pain, and seems pointless, but if there is no alternative, I have to try it - as a last resort.
So, what should I do next ? |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|