Hallo,
was muss ich denn
void PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po);
für fout übergeben, wenn nicht nach STDOUT ausgegeben werden soll? Ich würde z.b gern direkt in eine Datei schreiben…
steh voll aufm Schlauch
beho
Hallo,
was muss ich denn
void PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po);
für fout übergeben, wenn nicht nach STDOUT ausgegeben werden soll? Ich würde z.b gern direkt in eine Datei schreiben…
steh voll aufm Schlauch
beho
Ich würde sagen, einen Filedescriptor, den du vorher mit fopen() geöffnet hast.
Hallo,
ich seh grad, ich hab ja schon mit stdout probleme… Müsste die Ausgabe nich in der Konsole erscheinen?!?
#include <stdlib.h>
#include "libpq-fe.h"
void main()
{
pqbool f=0;
char *conninfo;
PGconn *conn;
PGresult *res;
PQprintOpt options = {0};
conninfo = "dont show";
conn = PQconnectdb(conninfo);
res = PQexec(conn, "SELECT a1 FROM t1;");
options.header = f;
options.align = f;
options.standard = f;
options.html3 = f;
options.expanded = f;
options.pager = f;
options.fieldSep = ";";
options.tableOpt = "";
options.caption ="";
options.fieldName = "";
PQprint(stdout,res,&options);
PQclear(res);
PQfinish(conn);
return;
}
Stattdessen ended das Programm einfach wieder mit Code “0”…
Hast du mal versucht, eine Datei zum Schreiben zu öffnen und den Filedescriptor dort anzugeben? Funktioniert das? Und ich kann mir nicht vorstellen, das keine der Funktionen keinen Rückgabewert liefert, den man auswerten könnte …
Du prüfst ja praktisch überhaupt nichts und wunderst dich, wenn die Ergebnisse nicht deinen Erwartungen entsprechen. Schlechter Programmierstil.
sry, schlag mich! ich depp hatte den DB server gestopt…
stdout funktioniert. Aber:
Deine Schelte ernstnehmend fange ich die Statusmessages ab.
#include <stdlib.h>
#include "libpq-fe.h"
void main()
{
pqbool f=0;
pqbool t=1;
char *conninfo;
PGconn *conn;
PGresult *res;
PQprintOpt options = {0};
int nFields=0;
int i=0,
j=0;
/* set connection string and connect */
conninfo = "***";
conn = PQconnectdb(conninfo);
/* connection ok? */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
PQfinish(conn);
exit(1);
}
/* send querry against db*/
res = PQexec(conn, "SELECT c1 FROM massdata.c1 LIMIT 10");
/* result status ok? raises pointerexception*/
//fprintf(stderr, "command failed: %s", PQresultStatus(res));
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "command failed: %s", PQerrorMessage(res));
PQclear(res);
PQfinish(conn);
exit(1);
}
/* first, print out the attribute names */
nFields = PQnfields(res);
for (i = 0; i < nFields; i++)
printf("%-15s", PQfname(res, i));
printf("\n\n");
/* next, print out the rows */
for (i = 0; i < PQntuples(res); i++)
{
for (j = 0; j < nFields; j++)
printf("%-15s", PQgetvalue(res, i, j));
printf("\n");
}
options.header = f;
options.align = f;
options.fieldSep = "|";
options.standard = f;
options.html3 = f;
options.expanded = f;
options.pager = f;
options.fieldSep = "|";
options.tableOpt = "";
options.caption ="";
options.fieldName = "";
PQprint(stdout,res,&options);
PQclear(res);
PQfinish(conn);
return;
}
verwirrend ist, dass ich trotz gültigen SQL-Statements in if (PQresultStatus(res) != PGRES_COMMAND_OK) ohne Ausgabe der Fehlermeldung hängen bleibe. Kommentier ich die aus, bekomm ich die Ausgabe auf STDOUT wie gewünscht.
Im weiteren bekomm ich dann ne Pointerexception sobald ich options.* bestücken will…
Grüße
beho
Ich schätze, dein Fehler liegt hier:
PGRES_COMMAND_OK ist für Befehle, die keine Daten zurückliefern.
PGRES_TUPLES_OK ist für Befehle, die Daten zurückliefern (wie SELECT).
Steht fein säuberlich hier beschrieben:
PostgreSQL: Documentation: Manuals: PostgreSQL 8.2: Command Execution Functions
argh! und schon wieder haste recht! dank dir! Nun, dann kann ich nun endlich an die Funktion die mich eigentlich interessiert, nämlich PQprint:
wie gesagt, hier knall er sofort weg, sobald ich die options bestücken will
options.header = 0;
Was genau heisst “knallt weg”?
Aus der Doku: “Note that it assumes all the data is in text format.”.
Vielleicht liegt es daran …
das bezieht sich auf die unterscheidung von binärdaten und text… es kommt alles als text was nicht binär ist…
if(( PQresultStatus( res ) == PGRES_COMMAND_OK ) ||
( PQresultStatus( res ) == PGRES_TUPLES_OK ))
{
PQprintOpt options = {0};
options.header = 1; /* Ask for column headers */
options.align = 1; /* Pad short columns for alignment */
options.fieldSep = "|"; /* Use a pipe as the field separator*/
PQprint( stdout, res, &options );
}
ich hab mir dieses von Client 3Simple ProcessingPQexec() and PQprint() (zeile20) mal reingeholt. da reißt er keine pointerexcepion mehr beim ersten options.*
sondern erst beim aufruf von PQprint. ICh vermute also ich muss die restlichen Variablen in PQprintOpt ebenfalls in geeigneter weise bestücken…
Was genau ist ‘options’ bei dir und wie wird es definiert?
Wenn dein Programm schon beim Setzen von options abstürzt, deutet das auf irgendeine Speicherverletzung hin.
options ist ein struct vom typ:
typedef struct {
pqbool header; /* print output field headings and row count */
pqbool align; /* fill align the fields */
pqbool standard; /* old brain dead format */
pqbool html3; /* output HTML tables */
pqbool expanded; /* expand tables */
pqbool pager; /* use pager for output if needed */
char *fieldSep; /* field separator */
char *tableOpt; /* attributes for HTML table element */
char *caption; /* HTML table caption */
char **fieldName; /* null-terminated array of replacement field names */
} PQprintOpt;
wie gesagt, auch da komm ich durch (zumindest siehts so aus). vermutlich muss ich dies hier noch ändern: options.fieldName = “”; speicher dürft ich da aber nicht reservieren müssen oder?
die zugriffsverletzung passiert jetzt bei PQprint( stdout, res, &options );
btw.: dicken dank für deine hilfe!!!
Ok, dann zeig mal den kompletten relevanten Code bitte, wie du das compilierst und wie du das ausführst.
Optional könntest du das auch mal mit Debuggingsymbolen compilieren und in einem Debugger laufen lassen.
ok, also hier mein testprog:
#include <stdlib.h>
#include <stdio.h>
#include <libpq-fe.h>
int main()
{
pqbool f=0;
pqbool t=1;
char *conninfo;
PGconn *conn;
PGresult *res;
PQprintOpt options = {0};
int nFields=0;
int i=0,
j=0;
/* set connection string and connect */
conninfo = "***";
conn = PQconnectdb(conninfo);
/* connection ok? */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
PQfinish(conn);
exit(1);
}
/* send querry against db*/
res = PQexec(conn, "SELECT mist FROM t_test;");
if(( PQresultStatus( res ) == PGRES_COMMAND_OK ) ||
( PQresultStatus( res ) == PGRES_TUPLES_OK ))
{
PQprintOpt options = {0};
options.header = 1;
options.align = 1;
options.standard = 1;
options.html3 = 1;
options.expanded = 1;
options.pager = 1;
options.fieldSep = "|";
options.tableOpt = "";
options.caption = "";
options.fieldName = "";
PQprint( stdout, res, &options );
}
else
{
printf( "%s\n", PQresStatus( PQresultStatus( res )));
printf( "%s\n", PQresultErrorMessage( res ));
}
PQclear(res);
PQfinish(conn);
return 0;
}
hier die Optionen der VS2005 Befehlszeile:
/Od /I "C:\Programme\PostgreSQL\8.2\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /nologo /c /ZI /TC /errorReport:prompt
das heißt also:
Ohne Optimierung,
Aufrufdkonventionen: __cdecl (/Gd)
Kompilierungsart: C (/TC)
zum stand der dinge:
ich denke das struct PQprintOpt ist, welches mir Fehler verursacht. genauer:
char **fieldName;
ich hab folgende Varianten probiert um Fieldname ein 0terminiertes Array zu übergeben, diese hier laufen über die Zeile drüber und verursachen erst beim Aufruf von PQprint eine Zugriffsverletzung:
options.fieldName = "";
options.fieldName = "\0";
options.fieldName = "Hallo Welt";
options.fieldName = "Hallo Welt\0";
während diese hier und Varianten schon selbst eine Zugriffsverletzung verursachen:
options.fieldName[0] = "";
nach dem was ich so recherchiert hab:
Re: PQprint under Windows
Ist das wohl ein fehler in der libpq.dll. ich versuche grad die dll selbstzukompilieren in der hoffnung das das hilft.
Eine andere Überlegung wäre explizit Speicher zu reservieren - wobei fraglich ist, ob das hilft.
halbwegs verzweifelt
beho
Ich glaube, diese letzte Zeile macht nicht, was du möchtest.
Du setzt nur den Wert des ersten Feldes in ‘options’ auf 0. Würde diese Deklaration am Anfang der Funktion stehen, würde dir C den Rest wohl mit ‘zero’ füllen.
Da du die Zeile aber mitten in der Funktion schreibst, passiert das nicht.
Müsste das nicht ausserdem ‘= {f}’ heissen, wenn du den Wert setzen möchtest?
Es ist zum schreien!
Mein Code war korrekt. was nicht korrekt war, war libpq.dll… Nachdem ich das C-Interface neu kompiliert hab, funktioniert alles fehlerfrei. Ich hatte diesen Verdacht von Anfang an und hätte dem wohl auch nachgehen sollen
Wers übrigens nicht glaubt - ich bin bzw. war nicht der einzige mit diesem Problem:
Re: PQprint under Windows
Über die Ursache dieses Phänomen braucht man denke ich auch nicht lange spekulieren, ich würde vermuten es liegt schlicht an der Verwendung von Pointergeschubse wie diesem hier
Char **Fieldname;
Ich danke euch für eure Hilfe!!!
beho
Fein fein
akretschmer: Rechnung!