tags:

views:

580

answers:

9

LS,

Basically my code opens a connection to the Excel file, performs an UPDATE query, and closes the connection again.

When I execute a SELECT on the file, and output it, it does reflect the updated data, but when I close the connection and send the file to the user, it doesn't have the data in it.

It seems that the data is written after the script is fully finished, because the (remote) file is correct after the request.

Kind regards,

Matthias Vance

Edit:

// Pseudo code
$excel = new Excel($path);
$excel->query("SELECT $columnNames, '' AS newCol1, '' AS newCol2 INTO [$newFile].[newSheet] FROM [$sheet]);
$excel->close();
$excel = new Excel($newFile);
$excel->query("UPDATE [newSheet] SET newCol1 = 'x'");
$excel->close();
A: 

In an external datarange's properties you can select to 'Remove external data from worksheet before saving'. Is that checked or unchecked in this case? The query may work but might act as you describe, not saving the data in the file.

datatoo
Well it does save the data to the file when PHP closes all handles, so that's not a problem. The problem is it doesn't save when I close the connection.
Matthias Vance
does the file sent to the user have an external data range that seems to be refreshable on their receiving end? but nothing is in the range?
datatoo
I added an example of my code. I hope this clarifies the situation.
Matthias Vance
Besides,$excel->query("UPDATE [newSheet] SET newCol1 = 'x'");don't you need an save in here prior to$excel->close();
datatoo
Well, the data -does- get saved to the file when all handles are closed. The Excel class just uses an ODBC connection.
Matthias Vance
Just to clarify, since i was downvoted anyway. The page you want is generated, but the data is not saved and persistent when the user opens it later. Correct?I am still curious if there is an empty external data range in the sheet.
datatoo
No, that's not correct. The files does get saved after PHP finishes executing (and all handles close). So if I output the file to the user in the same request, it will not be updated correctly.
Matthias Vance
... no external data range is left defined in the workbook?
datatoo
No, there is no external data range. The file gets downloaded correctly after the request is finished.
Matthias Vance
A: 

Not 100% sure of this, but I'd guess that you probably need to add a COMMIT statement.

Russell Newquist
The PHP manual states this: "By default, auto-commit is on for a connection. Disabling auto-commit is equivalent with starting a transaction.".
Matthias Vance
Ah well, it was worth a shot.
Russell Newquist
-1 because it'll otherwise be auto-accepted.
Matthias Vance
A: 

I don't have Perl background, so please be kind.

Try and call Save on Workbook, before calling Excel->Close.
You should be able to get reference to the workbook, using the Excel instance that you have, I suppose.

shahkalpesh
I believe Matthias mentioned using Php not Perl
Adrian
I am indeed using PHP, and I cannot get any references, since my Excel object is just something that wraps around ODBC.
Matthias Vance
A: 

Microsoft ODBC Desktop Database Drivers UPDATE Statement Limitations Updated 2009

When the Microsoft Excel driver is used, it is possible to update values, but a row cannot be deleted from a table based on a Microsoft Excel spreadsheet. As a result, the UPDATE statement is not considered officially supported by the Microsoft Excel driver. Only the INSERT statement is considered supported.

More details here: Microsoft Excel Driver Programming Considerations

Depending on your version of ODBC driver, this may or may not be still the case.

Related pages:

Adrian
As I said before, UPDATE -does- work. The files -do- get written correctly, but only after the PHP script is finished.
Matthias Vance
A: 

Perhaps you should consider avoiding using the "old style" ODBC API and use the XML file format. This is a good tutorial showing how to read and write data from/to and Excel worksheet, from PHP, using XML:

Read and write Excel data with PHP

If you think XML is the way to go, have a look here:

You can also consider using a dedicated PHP class for writing into an Excel file:

(a question on this topic already exists on StackOverflow)

Adrian
XML is not an option, I need to support default Excel file formats. Also, I cannot use PHP classes which read/write directly from/to the file since I need the database/query functionality.
Matthias Vance
Don't forget that XLSX IS an XML file :)e.g. http://en.wikipedia.org/wiki/Microsoft_Office_XML_formats#Excel_XML_Spreadsheet_example
Adrian
That, I do know. But I also have to support 2003 files, and I need the database functionality ;)
Matthias Vance
A: 

Try turning autocommit on on using odbc-autocommit

Alternatively, ensure you use complete the transaction with odbc-commit or odbc-rollback before calling odbc_close

*Note: odbc_close function will fail if there are open transactions on this connection. The connection will remain open in this case.*

e.g.

$conn = odbc_connect($odbc,$user,$password)
    or die($error);

odbc_autocommit($conn, FALSE);

odbc_exec($conn, $query1);

if (!odbc_error())
      odbc_commit($conn);
else
      odbc_rollback($conn);

odbc_close($conn);
Adrian
As I stated before from the PHP manual: "By default, auto-commit is on for a connection. Disabling auto-commit is equivalent with starting a transaction.". I do not use transactions.
Matthias Vance
You do use transactions, even this is not transparent. Having AutoCommit set to ON is equivalent with starting and finishing a transaction for every read and write operation. You can try and take control of the process by setting the AutoCommit to OFF and have explicit COMMIT/ROLLBACK statements.
Adrian
I tried that, and it didn't work.
Matthias Vance
A: 

Perhaps a:

$excel = null;
unset($excel);

after the last close will fix the thing (I think excel->close() doesn't free the excel instance you use for the query)

RC
This doesn't work. I have tested it. The reason why it doesn't work is because the Excel object doesn't have any handles.
Matthias Vance
A: 

I am still using the workaround I noted before, first, I request the file that processes the Excel files, and then do another request to a script that outputs them.

Matthias Vance
+1  A: 

I am having the same issue. I am using direct ODBC API and can create a table in Excel using DDL and insert rows into the table and re-retrieve the inserted rows successfully, even after I disconnect and reconnect to the data source using ODBC; but as soon as my application exits, all the updates and created table in Excel are gone. Still searching for Solution.

Notes: Excel ODBC driver does not support transactions and is always in auto-commit mode.

OK. Found out why that was happening. Make sure all disconnect code paths call ::SQLDisconnect before freeing connection handle, otherwise the updates disappear. Example,

    if (!m_bConnectionDead) {

        if (IsTransactionCapable() && !IsAutoCommit())
            SQLTransact(m_bCommitOnDisconnect ? SQL_COMMIT : SQL_ROLLBACK);

        SQLRETURN rc = ::SQLDisconnect(m_hdbc);

        if (!RC_SUCCESS(rc) || rc == SQL_SUCCESS_WITH_INFO)
            CZDMsg::GetInstance()->DiagSQLError(this, NULL, rc, ROUTINE);
    }

    if (m_hdbc != NULL) {

        ::SQLFreeHandle(SQL_HANDLE_DBC, m_hdbc);
        m_hdbc = NULL;
    }

    if (m_henv != NULL) {

        ::SQLFreeHandle(SQL_HANDLE_ENV, m_henv);
        m_henv = NULL;
    }
}
Farid Z
My updates don't disappear when my script finishes executing. The problem is that they're not written when I disconnect (but are when the script finishes).
Matthias Vance
When I had this issue my updates did not disappear either while my application was still running. The updates disappeared when my application exited. You are not calling ::SQLDisconnect on the ODBC connection before freeing connection handles. As long your process is still running the updates are there, but once your process exits (and did not call ::SQLDisconnect) the updates are gone
Farid Z