MS-SQL 7 versus MS-SQL 2000
| From: | Vincent Oostindie | Date: | Wed, 08 May 2002 09:59:43 +0000 |
| Subject: | MS-SQL 7 versus MS-SQL 2000 | ||
| Groups: | php.general | ||
| Request: | Send a blank email to php-general+get-96557@lists.php.net to get a copy of this message | ||
Hello there,
I have a Serious Problem :(
I wrote a web-application that allows database administrators to edit the
contents of a database. Not in a phpMyAdmin-like manner, as that is too
close to the data for 'normal users' (direct table access). It is more
like Microsoft Access (yuk! :)), but in a web-interface.
This application is more or less independent of the DBMS that is used. It
currently supports MySQL, PostgreSQL, MS-SQL and Sybase. In the MS-SQL
case, I have always tested it with version 2000 (or 8), which works fine.
One of my customers has MS-SQL 7, and now I suddenly run into problems.
The problems have nothing to do with the fact that MS-SQL 7 - like MS-SQL
2000 - is not a real relational DBMS. Whereas in MS-SQL 2000 you can use
referential integrity to cascade deletetion and such, in MS-SQL 7 this has
to be done by hand. I'm perfectly aware of this, so this is not where my
problems lie.
Strangely enough, my problem seems to be with PHP. Let me explain the
steps taken when I insert a new record: - A form is posted, containing
values for a new record - The new record is inserted into the database -
If a new record was succesfully created, I redirect to a new page, showing
the newly inserted record - If the record could not be inserted, I
redisplay the insertion form and show some meaningful error message like
'not all fields have a value' or 'unique field already exists'.
This sounds pretty logical and simple I think, and so is the
implementation:
// For clarity: this is a class-method, not a function...
function handleInsert()
{
$command = $this->table->getInsertCommand();
if ($command->run()) {
$record = &$command->getInsertedRecord();
$url = new Url($_SERVER['PHP_SELF']);
$url->setParameter('key', $record->getKey());
header('Location: ' . $url->getUrl());
}
$this->setMessage('Error: ' . $command->getErrorMessage());
$this->buildInsertWindow();
}
Even though nobody here knows about the classes I use, I think the idea is
pretty clear. Also, it works very well with MySQL, PostgreSQL, MS-SQL 2000
and Sybase. As soon as I run this code on MS-SQL 7, things go wrong:
everytime I do an insert I get an error 'This statement has been
cancelled', but the record is inserted successfully!. I thought that this
is very strange, so I dug a little deeper. It turns out that the code
above is executed many times instead of just once: the first time the
record is inserted successfully, but the script simply continues to insert
new records. If one of the fields in the table is unique, this means that
the second time the code is executed, the insertion fails, resulting in
mentioned error message. If there is no unique key in a table (or the
unique key is an AUTONUMBER or something), the record is inserted over and
over again until the script times out. This also happens if I do something
different than an insert, like a delete: the browser hangs for the maximum
execution time (30 seconds) and PHP times out. The same code is being
executed over and over again, deleting the same record over and over again
(which doesn't work, naturally).
I've done some searching, and I've made the following observations:
- The "header('Location :' ...')" works fine.
- The URL for the new page is based on the one from the current page.
In my implementation that means that whether to execute an insertion,
deletion or update depends on the POST-parameters passed to the script.
- Apparantly, the POST-variables for the current page are saved and
passed on to the next page when I execute the header-function, so, in
effect, the script opens itself again.
The strange thing is: this seems to have nothing to do with the DBMS I'm
using, but with PHP instead. However I know that this isn't true, as the
code runs fine with different DBMS's!
To be honest, I'm completely baffled. I've been looking into this for a
week now, and still have no idea what to do. I'm seriously considering to
tell my customer to upgrade to MS-SQL 2000, or to just forget about the
whole thing.
I hope I'm not the first to experience this problem, so hopefully somebody
out here can nudge me in the right direction.
Thanks in advance!
Vincent