Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

PB10 and MS SQL Server

Status
Not open for further replies.

bigbillmac

Programmer
Jan 31, 2005
24
0
0
GB
Can anyone help?

I have an application that was originally written under PB7. I have now upgraded to PB10, which is infinitely more stable in the development environment - eg I can now actually use the debugger with confidence.

However, I have a really serious issue - transaction processing in SQL Server.

The transaction processing is carried out with the familiar statements, such as:

BEGIN TRANSACTION A

select ....
update ...
etc

COMMIT TRANSACTION A

The problem is very interment, and is different on different PCs but when you get it then it stays put and will always do it. But other PCs are getting the problem on processes where I am not.

The problem manifests itself as an error when I try to do the COMMIT TRANSACTION and I get the following conditions in SQLCA:

sqlCode = -1
sqlDbCode = 3902
sqlErrText = SQLSTATE = 25000
Microsoft OLE DB Provider for SQL Server
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.

The above errors was given by the code:
EXECUTE IMMEDIATE "BEGIN TRANSACTION";
UPDATE parameters SET last_surety = last_surety + 1;
SELECT last_surety INTO :ll_ret FROM parameters;
EXECUTE IMMEDIATE "COMMIT TRANSACTION";

f_DispSqlErrors(ls_func_name + "1")

NB the function f_DispSqlErrors() displays and formats the error message after testing sqlCode.

BTW the above is not the actual code used, the code used is a series of methods in an extension of the transaction class, but essentially the above code is what it does with a very simple transaction as the one above. And it also gives exactly the same error message.

I am confident that my code is OK because it worked in PB7. Btw in PB7 I was using the direct connection interface to SQL Server (only available in Enterprise version), in PB10 you are now forced to use OLE DB. So the connection software has completely changed.

The following Stored Procedure works OK:

CREATE PROCEDURE GetNextSurety AS

SET NOCOUNT OFF;

BEGIN TRANSACTION A

UPDATE parameters
SET last_surety = last_surety + 1

SELECT last_surety
FROM parameters

COMMIT TRANSACTION A
GO


which you can see is very similar to the code that fails.

So why is it that if PB is allowed to run the statements above it either:
Closes the transaction, or
Somehow never starts the transaction.

I can here what you are thinking:
Well if it works OK in a stored procedure then write all of the code fragments that use Transaction processing in stored procedures.

Yup this can be done and I am pretty sure it will solve the problem but some of the updates involved are very complex and might involve updates on as many 10 tables. This would lead to a series of very large and complex stored procedures and would take ages to write. I am basically trying to avoid this for one thing I am not 100% sure that it will work. Not only that testing a routine that works on my machine but not someone elses is a nightmare.

The MS trace program shows that when PB is issuing the staments a whole of trace and log statements are issued - but why should these cause a problem?

Bill
 
In our use of the OLE DB drivers for SQL Server, we set our initial connection with the transaction object with autocommit = TRUE. When we start a transaction we call a method which sets the autocommit property to false which forces a begin transaction statement. When we rollback a transaction or when we want to commit the transaction we set the autocommit property back to true which commits the transaction. This solved all problems with our db transactions.

This is all done via a modified n_tr object from the PFC.

Matt

"Nature forges everything on the anvil of time
 
Yes I noticed a similar post you made some time ago.

A while ago I created a new object that was a descendant of the transaction object. In this object I placed my begin/end/test/error check code and used SQL statements as decscribed above (eg Execute Immediate "BEGIN TRANSACTION"; etc), rather than the method you use. I think my reasoning was twofold:
1.) It was a 50% choice, and
2.) By using this method I might well get access to other transaction "properties and events" that might be available in SQL Server or any other database. Looking back the haul from this approach has been sparse.

ie I chose my method for no real reason!

Changing to your method - using sqlca.autoCommit = false/true - was very easy becuase any code requiring to be executed within a transaction calls these methods.

I have only had a chance to do one test - ie the one that fails on my pc, see my first post - and your method works perfectly here. So I am going to compile up a version and get it down to my clients (well one of them anyway) and let them test completely on their installation. At the moment I am running everything with NO transaction control - easy to do because of the use of the transaction object described above.

I will let you know.

Thanks for your post btw.

Always good to here from you.


Bill
 
I am migrating a PB 4 application TO PB 10 and we are using MS SQL SERVER 2000. How do you connect to a SQL 2K database inside of your app? What DSN do I use, (i.e. ODBC, OR OLE) to connect? I am currently using an application INI file where the servername, database and logid is stored.
 
PB 4 - wow? As I remember it was very stable - well 4a was.

You can use ODBC with no problems but I would reccommend OLE DB. If you use the db profile painter there is a preview tab which shows you the connection details, eg:

SQLCA.DBMS = "OLE DB"
SQLCA.LogId = "sa"
SQLCA.AutoCommit = False
SQLCA.DBParm = "PROVIDER='SQLOLEDB',DATASOURCE='ELROND\ELROND_DB',PROVIDERSTRING='CATALOG=AON'"

The server in the above has NO password (development machine), assuming that yours has then you will need to code this too.

The PB code below has the database, server and user names stored in the arrays - yes I know an array of structures or auto instantiated non-visual objects would have been more elegant. There is also another array is_pwd[] that contains the db password. These are all retrieved from an ini file (code not shown) and the password is encrypted to keep it away from prying eyes. Hence use of global function f_decrypt()
SQLCA.DBMS = "OLE DB"
SQLCA.AutoCommit = True
SQLCA.Database = is_db[resp]
SQLCA.ServerName = is_server[resp]
SQLCA.LogId = is_usr[resp]

sqlca.dbParm = "PROVIDER='SQLOLEDB',DATASOURCE='" + is_server[resp] + &
"',PROVIDERSTRING='database=" + is_db[resp] + &
";APP=BONDS'"

// is there a password
if (not f_empty(is_pwd[resp])) then
SQLCA.LogPass = f_decrypt(is_pwd[resp])
end if

setpointer(HourGlass!)

CONNECT using SQLCA ;

... test etc.


You will need OLE DB installed on your machine - I run Win2000 pro and it was installed as default. You will also have to have the MS SQL OLE DB Provider installed on your machine - again this was also installed by default on my machine.

To add to the confusion there is also an ODBC provider for OLE DB - which I find difficult to understand why. It's a bit like the ODBC driver supplied with JDBC - but here I can see the point of the ODBC-JDBC bridge. So make sure you have the MS Sql Server Provider.

If you look at mbalent's earlier post then it is wise to work with AutoCommit=true and control transactions the way he suggests. I have found with PB10 that each update that I have downloaded seems to change something to do with db access using OLE DB and the ability to use the SQL 2000 staement BEGIN TRANSACTION was lost. The problem is I am sure something to do with CURSORs - so use them very sparingly.

Hope this helps.

Bill
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top