Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SQLBindParameter ,Output, Var char -> warum keine Rückgabe?

11 views
Skip to first unread message

thomas kost

unread,
Jun 4, 2004, 9:48:36 AM6/4/04
to
hallo

ich nutze die ODBC-Funktion SQlBindparameter,MS SQL Server 2000 u
passenden Treiber
habe folgende Beispiel Procedure:

CREATE PROCEDURE [ReadAll] ( @Str varchar(255) OUTPUT) AS
Set @Str = 'hallo'
GO

und folgenden C++ Code(auszug) (nach SQLPrepare mit "call ReadAll(?)"
)

char buffer[255];
long size = sizeof(buffer) ;

sqlReturn = SQLBindParameter(StmtHndl,1,SQL_PARAM_OUTPUT,SQL_C_CHAR,SQL_VARCHAR,size,0,(void*)&buffer,size,&size);

dann natürlich SQLExecute ...

Ich bekomm einfach den String nicht heraus. (in MYSQL funzt es)
Ausserdem bin ich (oder war ich?) der meinung das bei SQL_PARAM_OUTPUT
die ColumnSize (im Beispiel das erste size) nicht nötig ist nur bei
Input Params.
Hat jemand eine Idee?

Falls jemand nach Möglichkeit eine gute deutsche Beschreibung der
Funktion irgendwo im Netz gesehen hat, wüsste ich auch gern wo die
ist. :)


Danke im Voraus

Elmar Boye

unread,
Jun 5, 2004, 11:30:44 AM6/5/04
to
Hallo Thomas,

thomas kost <j.hu...@freenet.de> schrieb ...


> ich nutze die ODBC-Funktion SQlBindparameter,MS SQL Server 2000 u
> passenden Treiber

passsend heisst hoffentlich aktuell, wegen
http://support.microsoft.com/?kbid=290175
FIX: SQL Server ODBC Driver Does Not Transfer Return Values
from Stored Procedures

> habe folgende Beispiel Procedure:
>
> CREATE PROCEDURE [ReadAll] ( @Str varchar(255) OUTPUT) AS
> Set @Str = 'hallo'
> GO
>
> und folgenden C++ Code(auszug) (nach SQLPrepare mit "call ReadAll(?)"
> )
>
> char buffer[255];
> long size = sizeof(buffer) ;
>
> sqlReturn =
> SQLBindParameter(StmtHndl,1,SQL_PARAM_OUTPUT,SQL_C_CHAR,SQL_VARCHAR,
> size,0,(void*)&buffer,size,&size);
>
> dann natürlich SQLExecute ...
>
> Ich bekomm einfach den String nicht heraus.

Da Deiner Prozedur ein einleitendes
SET NOCOUNT ON
fehlt, wird für jede Anweisung (auch SET ...) ein Resultset
zurückgeliefert, siehe auch: http://support.microsoft.com/?kbid=240882
Ausgabevariablen werden immer nach dem letzten Ergebnis geliefert,
und so wäre ein SQLMoreResults() erforderlich. Wo sinnvoll (meistens also)
sollte man aber schon wegen obigem Verhalten SET NOCOUNT ON verwenden.

> (in MYSQL funzt es)

zählt nicht ;-)

> Ausserdem bin ich (oder war ich?) der meinung das bei SQL_PARAM_OUTPUT
> die ColumnSize (im Beispiel das erste size) nicht nötig ist nur bei
> Input Params.

Doch ist es. Anhand der Grössenangabe wird nämlich der die Länge
für den Parameter, also VARCHAR(cbColDef) festgelegt.

> Hat jemand eine Idee?

Ein Auszug mit dem es funktioniert:

// Return Value
sqlrc = SQLBindParameter( hstmt,
1,
SQL_PARAM_OUTPUT,
SQL_C_LONG,
SQL_INTEGER,
0,
0,
&lReturnValue,
sizeof(lReturnValue),
&cbReturnValue);

// String Parameter
SQLBindParameter(hstmt,// SQLHSTMT hstmt,
2, // SQLUSMALLINT ipar,
SQL_PARAM_OUTPUT, // SQLSMALLINT fParamType,
SQL_C_CHAR, // SQLSMALLINT fCType,
SQL_VARCHAR, // SQLSMALLINT fSqlType,
OUTPUT_STRING_LEN, // SQLULEN cbColDef
0, // SQLSMALLINT ibScale
&szOutputString, // SQLPOINTER rgbValue
OUTPUT_STRING_LEN, // SQLLEN cbValueMax
&cbOutputString); // SQLLEN *pcbValue

sqlrc = SQLExecDirect(hstmt,
(SQLCHAR *)_T("{? = call ReadAll(?)}"), SQL_NTS );

if (sqlrc == SQL_SUCCESS)
{
// Ohne SET NOCOUNT ON erforderlich
sqlrc = SQLMoreResults(hstmt);
while (sqlrc != SQL_NO_DATA)
{
sqlrc = SQLMoreResults(hstmt);
}

// Ausgabeparameter werden nach dem letzten Ergebnis geliefert
if (cbOutputString > 0)
_tprintf(_T("%s\n"), szOutputString);
}


> Falls jemand nach Möglichkeit eine gute deutsche Beschreibung der
> Funktion irgendwo im Netz gesehen hat, wüsste ich auch gern wo die
> ist. :)

Deutsche Beschreibung für Entwicklerprodukte sind Mangelware, bei
etwas wie ODBC sowieso. Da musst Du Dich schon durch die MDAC Hilfe
durcharbeiten, die Bestandteil vom Platform SDK und gesammelt:
http://msdn.microsoft.com/data/downloads/

Und die Spezifika vom SQL Server Treiber findest Du in der
SQL Server Dokumentation zu ODBC. Nur ist auch die in der
deutschen Dokumentation englisch.

Gruss
Elmar

thomas kost

unread,
Jun 7, 2004, 5:23:47 AM6/7/04
to
hallo Elmar

> Da Deiner Prozedur ein einleitendes
> SET NOCOUNT ON
> fehlt, wird für jede Anweisung (auch SET ...) ein Resultset
> zurückgeliefert, siehe auch: http://support.microsoft.com/?kbid=240882
> Ausgabevariablen werden immer nach dem letzten Ergebnis geliefert,
> und so wäre ein SQLMoreResults() erforderlich. Wo sinnvoll (meistens also)
> sollte man aber schon wegen obigem Verhalten SET NOCOUNT ON verwenden.
>

Ok 'SET NOCOUNT ON ' hab ich eingefügt .... aber klappt trotzdem
nicht. auch mit der SqlMoreResult schleife nicht.
Hab vergessen zu erwähnen das es bei allen anderen Typen: SQL_Integer,
SQL_Double .... wunderbar funktioniert nur nicht bei varchar!!!

Ich glaub nicht das es daran liegt das ich statt der SQLExecDirekt
funktion nur die SQlExecute benutze ...

gruss thomas

Elmar Boye

unread,
Jun 7, 2004, 4:01:10 PM6/7/04
to
Hallo Thomas,

thomas kost <j.hu...@freenet.de> schrieb ...
>

>> Da Deiner Prozedur ein einleitendes
>> SET NOCOUNT ON
>> fehlt, wird für jede Anweisung (auch SET ...) ein Resultset
>> zurückgeliefert, siehe auch:
>> http://support.microsoft.com/?kbid=240882 Ausgabevariablen werden
>> immer nach dem letzten Ergebnis geliefert,
>> und so wäre ein SQLMoreResults() erforderlich. Wo sinnvoll (meistens
>> also) sollte man aber schon wegen obigem Verhalten SET NOCOUNT ON
>> verwenden.
>>
>
> Ok 'SET NOCOUNT ON ' hab ich eingefügt .... aber klappt trotzdem
> nicht. auch mit der SqlMoreResult schleife nicht.
> Hab vergessen zu erwähnen das es bei allen anderen Typen: SQL_Integer,
> SQL_Double .... wunderbar funktioniert nur nicht bei varchar!!!


Bei mir schon. Ich habe mal mein kleines VC++.NET Testprogrämmchen
abgestellt unter
http://www.elmarboye.de/download/odbcparam.zip

Im wesentlichen sollte das identisch sein. Wobei ich für VARCHAR
auch SQL_VARCHAR verwendet habe, da ansonsten die Daten unnötig mit
Leerzeichen aufgefüllt werden.

>
> Ich glaub nicht das es daran liegt das ich statt der SQLExecDirekt
> funktion nur die SQlExecute benutze ...

Vorausgesetzt Du hast SqlPrepare aufgerufen macht das keinen
Unterschied. Wie Du oben im Quellcode siehst, hatte ich die Variante
mal drin (ist auskommentiert).

Gruss
Elmar

0 new messages