HY000 - Mehrere Statments auf einer Verbindung?

23/06/2009 - 10:41 von Björn Dehmel | Report spam
Hallo zusammen,

von unserer iSeries bin ich es gewohnt, auf einer Connection beliebig viele
Statements ausführen zu können.
Dieses wollte ich jetzt für einen SQL Server 2008 adaptieren. Ich greife auf
diesen mittels eines SQLDriverConnect mit DRIVER={SQL Server} zu. Hole mir
dann 2 Statement-Handles und prepare diese. Den ersten Statement führe ich
nach den BindCol und BindParameter aus und fetche den ersten Datensatz. Jetzt
soll das zweite Statement executet werden, woraufhin ich die Fehlermeldung:
"HY000 - Die Verbindung ist mit Ergebnissen von einem anderen hstmt belegt"
bekomme.

In dem Sinne hat der Fehler ja Recht. Die Frage ist: Kann der Treiber zum
SQL Server keine mehreren ResultSets verarbeiten? Kann dieses wie beim .Net
Treiber mittels "MultipleActiveResultSets=TRUE" aktiviert werden? Oder bin
ich gezwungen mehrere Connections aufzubauen?

Gruß Björn


Hier mein Programmcode:
if (SQLAllocHandle (SQL_HANDLE_STMT, gl_SqlServerDbc, &hstmt1) == SQL_SUCCESS)
{
if (SQLAllocHandle (SQL_HANDLE_STMT, gl_SqlServerDbc, &hstmt2) ==
SQL_SUCCESS)
{
sqlreturn = SQLPrepare (hstmt1, (SQLCHAR *) szSQLString1, SQL_NTS);

if (sqlreturn == SQL_SUCCESS || sqlreturn == SQL_SUCCESS_WITH_INFO)
{
sqlreturn = SQLPrepare (hstmt2, (SQLCHAR *) szSQLString2, SQL_NTS);

if (sqlreturn == SQL_SUCCESS || sqlreturn == SQL_SUCCESS_WITH_INFO)
{
... Binds ...

sqlreturnQSData = SQLExecute (hstmt1);

if (sqlreturnQSData == SQL_SUCCESS || sqlreturnQSData ==
SQL_SUCCESS_WITH_INFO)
{
do
{
sqlreturnQSData = SQLFetch (hstmt1);

if (sqlreturnQSData == SQL_SUCCESS || sqlreturnQSData ==
SQL_SUCCESS_WITH_INFO)
{
sqlreturn = SQLExecute (hstmt2); // <- FEHLER
 

Lesen sie die antworten

#1 Elmar Boye
23/06/2009 - 11:37 | Warnen spam
Hallo Björn,

Björn Dehmel schrieb:
von unserer iSeries bin ich es gewohnt, auf einer Connection beliebig viele
Statements ausführen zu können.



Beim SQL Server ging das traditionell bis SQL Server 2005 nicht,
auch weil es im Regelfall ineffiziente Programme bedeutet.

In dem Sinne hat der Fehler ja Recht. Die Frage ist: Kann der Treiber zum
SQL Server keine mehreren ResultSets verarbeiten?



Der ursprüngliche SQL Server Treiber (DRIVER=SQLSRV32) kann dies
nicht, da er für SQL Server 2000 und früher gedacht ist, wo das
nicht ging.

Kann dieses wie beim .Net
Treiber mittels "MultipleActiveResultSets=TRUE" aktiviert werden?



Aktivieren kannst Du das beim SQL Server Native Client:
<URL:http://msdn.microsoft.com/de-de/lib...6.aspx>
"Verwenden von Multiple Active Result Sets (MARS)."

Hier mein Programmcode:



Günstiger ist es allerdings auf das Feature zu verzichten.
Effiziente Programme rufen die Daten von einem Cursor so schnell
wie möglich ab, um die Zeit die Daten gesperrt werden zu minimieren.

Zum einen degeneriert MARS bei mehr vielen (10) aktiven Statements
Und in Verbindung mit Transaktionen gibt es schnell Probleme,
wie Blockierungen und Deadlocks. Dem man dann zwar wiederum
mit Snapshot Isolierungen entgegenwirken kann. Aber am Ende
wird alles nur komplizierter, nicht einfacher.

Auch wenn es mit puren C etwas mühsamer ist als in .NET
Daten in Listen zu verwalten. Willst Du effizienter programmieren
verwende gleich .NET (da gibts alles das) oder C++ mit Templates.

BTW: SQLPrepare bringt bei SQL Server 2008 nichts, und kann
sich sogar negativ auf die Leistung auswirken:
<URL:http://msdn.microsoft.com/de-de/lib...7.aspx>

Gruß Elmar

Ähnliche fragen