logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
SQLExecDirect & INSERT INTO not working
Goto page 1, 2  Next
 
Post new topic   Reply to topic    nwnx.org Forum Index -> Database related
View previous topic :: View next topic  
Author Message
Pyridon



Joined: 07 Oct 2005
Posts: 9

PostPosted: Fri Oct 07, 2005 19:39    Post subject: SQLExecDirect & INSERT INTO not working Reply with quote

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
View user's profile Send private message
Pyridon



Joined: 07 Oct 2005
Posts: 9

PostPosted: Sat Oct 08, 2005 10:07    Post subject: Reply with quote

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
View user's profile Send private message
Acrodania



Joined: 02 Jan 2005
Posts: 208

PostPosted: Sat Oct 08, 2005 23:42    Post subject: Reply with quote

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
View user's profile Send private message
Pyridon



Joined: 07 Oct 2005
Posts: 9

PostPosted: Sun Oct 09, 2005 0:29    Post subject: Reply with quote

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
View user's profile Send private message
Acrodania



Joined: 02 Jan 2005
Posts: 208

PostPosted: Sun Oct 09, 2005 1:11    Post subject: Reply with quote

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 Smile 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
View user's profile Send private message
Gryphyn



Joined: 20 Jan 2005
Posts: 431

PostPosted: Sun Oct 09, 2005 8:39    Post subject: Reply with quote

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
View user's profile Send private message
Pyridon



Joined: 07 Oct 2005
Posts: 9

PostPosted: Sun Oct 09, 2005 20:55    Post subject: Reply with quote

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
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Sun Oct 09, 2005 22:41    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website MSN Messenger
Acrodania



Joined: 02 Jan 2005
Posts: 208

PostPosted: Mon Oct 10, 2005 1:20    Post subject: Reply with quote

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 Rolling Eyes 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. Smile
Back to top
View user's profile Send private message
Gryphyn



Joined: 20 Jan 2005
Posts: 431

PostPosted: Mon Oct 10, 2005 5:21    Post subject: Reply with quote

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
View user's profile Send private message
Lokey



Joined: 02 Jan 2005
Posts: 158

PostPosted: Mon Oct 10, 2005 13:20    Post subject: Reply with quote

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 Wink
Back to top
View user's profile Send private message
odenien



Joined: 26 Sep 2005
Posts: 37

PostPosted: Mon Oct 10, 2005 13:23    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
monezz



Joined: 03 Jan 2005
Posts: 52
Location: The Netherlands

PostPosted: Mon Oct 10, 2005 15:44    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
odenien



Joined: 26 Sep 2005
Posts: 37

PostPosted: Tue Oct 11, 2005 13:46    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
Pyridon



Joined: 07 Oct 2005
Posts: 9

PostPosted: Tue Oct 11, 2005 23:49    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> Database related All times are GMT + 2 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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