applikation----x----odbc driver manager----foobar ODBC driver----foobar database

Relaterede dokumenter
MySQL C API. Denne artikel beskriver hvordan man bruger MySQL C API. Der er beskrivelse af build med forskellige compilere.

Forskellige databaser

Den forudsætter kendskab til C++ og lidt kendskab til SQL og MySQL C API.

Databaseadgang fra Java

Introduktion til SQL queries

Prepared Statements. Denne artikel beskriver hvorfor prepared statements er gode. Den forudsætter lidt kendskab til Java og JDBC.

Skrevet den 18. Feb 2010 af arne_v I kategorien Programmering / Visual Basic.NET

Parameters. Denne artikel beskriver hvorfor parameters er gode. Den forudsætter lidt kendskab til C# og ADO.NET.

Listen over reserverede ord er meget lang, men de væsentligste vil jeg beskrive her i denne artikel:

Java web applikationer med Tomcat

Database programmerings tips

Indholdsfortegnelse Databaser og PHP... 3 Opgave... 4 Opgave... 5 Opgave... 6 Sidste opgave er en lille gæstebog... 7 Kilder og nyttige links:...

Database design for begyndere

Database tips. Den forudsætter lidt kendskab til SQL men er for mindre erfarne. Denne guide er oprindeligt udgivet på Eksperten.dk

Delphi og Databaser for begyndere

Ratingsystem i PHP og MySQL

PID2000 Archive Service

Dynamisk PHP design OPDATERET

Send fra Java. Denne artikel fortæller hvad man skal bruge og hvordan man skal kode for at sende fra Java.

Forskellige Java versioner

Import af rekursivt (parent-child) hierarki i Palo

ODBC made easy på dansk (når bare man ved hvordan) Jesper Michelsen, Data warehouse & Analyse

SQL for MySQL-begyndere

I mit script tager jeg højde for det problem ved, at gemme et unikt tal mellem 0-9 på 6 cifre og derved vil de så blive vist som 2 online.

Program Dokumentation PC Software Skrevet af. Gruppen. Version 1.0

RMI introduktion. Denne artikel beskriver Java RMI (Remtote Method Invocation).

Arkitektur for begyndere

JNI. Denne artikel beskriver JNI (Java Native Interface) som er måden hvorpå Java kan kalde native kode.

Singleton pattern i Java

Uploade billeder eller andre filer ved hjælp af php og mysql

Rigtig SQL Programmering

Tagwall med Php & MySQL

Hvilket sprog er hurtigst

MySQL i Java. Tutorial lavet af Jákup W. Hansen TSU semester 05.januar 2007

RMI avanceret. Denne artikel beskriver nogle mere avancerede features i RMI. Den gør det muligt at lave mere realistiske applikationer.

Foto-Applikation Dokumentation. Et Kod-i-Ferien projekt

En Kort Introduktion til Oracle

I denne artikel vil jeg gennemgå hvordan en side for RSS "Live Bogmærke" kan se ud.

Bemærk! Et PHP script har kun brug for at forbinde én gang til databaseserveren. Det kan så sagtens udføre flere kommandoer vha. denne forbindelse.

Loginsystem (med MySQL)

Begrynder til at lave log ind system

Excel som database i ASP via ADO

Denne artikel gennemgår kort nogle mulighederne for brug af XML i ASP. Det sker ved brug af eksempler. Eksemplerne vil være i VBS.

Opret ODBC datakilde Vejledning

Eksempel på en database: studenter, kurser, eksamener

Database for udviklere. Jan Lund Madsen PBS10107

Parameterisering af databasekald med ASP og ADO

Tilfældige tal. Denne artikel introducerer generering af tilfældige tal og viser lidt om hvad man kan og ikke mindst hvad man ikke bør bruge.

Introduktion til Oracle, Datalogi, RUC Af: Jens Lauterbach 2002

Samspillet mellem databaser og kort styres af GeoCAD programmet GeoDB.

Hvorfor skal vi bruge objekt orienteret databaser?

Loginsystem med PHP4, klasser, sessions og MySQL database

Gæstebog med validering opbygget med MySQL

Endnu mere om tilfældige tal

Eksamen, DSDS, efterår 2007

Procesbeskrivelse - Webprogrammering

PHP Pagination. Denne guide er oprindeligt udgivet på Eksperten.dk. Skrevet den 01. May 2011 af dab93 I kategorien Programmering / Andre

PHP 3 UGERS FORLØB PHP, MYSQL & SQL

Log ind med PHP. Denne guide er oprindeligt udgivet på Eksperten.dk. Skrevet den 09. May 2011 af dab93 I kategorien Programmering / Andre

Design Diaries.

MsSQL: Basal performance tuning, part 1

I denne arktikle går jeg gennem Slet, Ret og Opret data i en MySQL database. der er også en lille del i den hvor den postere datanen ud i en løkke

I denne artikel vil du ved hjælp af arrays kunne afrunde et decimaltal til et helt tal.

Web- og serverprogrammering

DB undervisning 01-01

Reeksamen, DSDS, forår 2008

PROJEKT 3. The Design Diaries. LINK TIL BLOG: Af Mikkel Borg Svendsen & Sebastian Frank MUL B

Introduction til.net remoting i VB.NET

De vigtigste SQL-sætninger. SQL kap Oprette database. DDL og DML

Programmering i C Intro og grundlæggende C 5. marts 2007

SQL ny front-end

Hej alle sammen, nu fjerner vi lige mystikken om alle de "ulovlige tags" her på eksperten.dk

Test med NUnit. Denne artikel introducerer NUnit. Den forklarer ideen med NUnit. Og den viser hvordan man konkret bruger det.

I denne artikel vil vi bruge en User klasse som vi så vil gruppere på forskellige måder.

Introduktion til ant. Denne artikel beskriver Apache ant, som er et værktøj til at builde Java applikationer med.

Den forudsætter kendskab til XML og VB.NET men ikke til brug af XML i VB.NET.

Data lagring. 2. iteration (implement backend)

Web 2.0. World Wide Web (www)

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { int wmid, wmevent; programmering med

Eksamen, DSDS, forår 2008

Sidste forelæsning. Jacob Aae Mikkelsen. 28. april 2013 IMADA. Jacob Aae Mikkelsen (IMADA) Sidste forelæsning 28.

JSP, Tomcat. Tutorial lavet af Jákup W. Hansen TSU semester 10.october 2007

Værktøjer fra værktøjskassen. Søren Breddam, Stevns Kommune

Delphi - CrackMe og Keygen

Microsoft Log Parser, Windows logfil analyse

PHP guide af Daniel Pedersen

Derfor vil jeg bygge dette eksempel på een table hvor der kan tilkyttes personer til ALLE noder og der kan tilføjes et vilkårligt antal niveauer

Afsending af s vha. ASP

LotusPhere comes to you IM Agent Manager - IM Support - Sametime / 27 Tobias Fonsmark -

Arrays i PHP. Denne guide er oprindeligt udgivet på Eksperten.dk. Skrevet den 04. Feb 2009 af taskmgr I kategorien Programmering / PHP

Installationsguide til Oracle Database XE 10.2 og APEX 3.1.1

PHP Quick Teknisk Ordbog

Data load og udtræk. 2. iteration: implmentation (test af backend) PHP mysql. Loade og parse XML (SimpleXML, Xpath) Filhåndtering i PHP JSON

Logging i Java. Den forudsætter kendskab til Java og noget generel udviklings erfaring. Denne guide er oprindeligt udgivet på Eksperten.

Threads i Java. Denne artikel giver en introduktion til threads i Java. Den beskriver hvad tråde er og forklarer hvordan de bruges i Java

Test med JUnit 3. Denne artikel introducerer JUnit 3. Den forklarer ideen med JUnit. Og den viser hvordan man konkret bruger det.

Udvikling af DOTNET applikationer til MicroStation i C#

Få sin querystring til at fungere. (Nybegyndere)

Introduction til.net remoting i C#

Undtagelseshåndtering i C#

Transkript:

Denne guide er oprindeligt udgivet på Eksperten.dk ODBC i C/C++ Denne artikel beskriver hvordan man bruger ODBC i C/C++. Der er beskrivelse af build med forskellige compilere. Den forudsætter lidt kendskab til C/C++ og SQL. Skrevet den 04. Feb 2009 af arne_v I kategorien Programmering / C/C++ Historie: V1.0-07/03/2004 - original V1.1-14/12/2007 - close cursor V1.2-26/12/2008 - små ændringer ODBC Mange kender ODBC (Open Database Connectivity) og har brugt det, men meget få er klar over at det i virkeligheden er et C API. ODBC er opfundet for at give et database uafhængigt API. Det fungerer som: applikation----odbc driver manager----foobar ODBC driver----foobar database ODBC definerer nogle standard C funktioner som man kan kalde uanset hvad databasen er. De fleste kender nok ODBC som: applikation----x----odbc driver manager----foobar ODBC driver----foobar database hvor det mellem liggende lag X gør det nemt at bruge ODBC fra Access, ASP etc., men det er stadig de samme C funktioner der kaldes. Det er bare koden i X som kalder dem. Og slut brugeren får et lidt nemmere interface. Denne artikel vil beskrive hvordan man lave simple forespørgsler og opdateringer i en database via ODBC. Man kan også få ODBC til ikke Windows platforme. Men de er ikke så meget brugte (embedded SQL er mere udbredt). Og jeg har aldrig prøvet det. Så det vil jeg ikke komme ind på. Jeg formoder at API'et er det samme. ODBC API dokumentationen er online her: <a href="http://msdn.microsoft.com/en-us/library/ms710154.aspx">http://msdn.microsoft.com/en-us/library/ ms710154.aspx</a>

Fordele og ulemper Fordele: - virker med alle database (næsten alle databaser har en ODBC driver) - virker med alle compilere (kræver ikke C++, MFC, ATL eller andet) - rimeligt simpelt at forstå Ulemper: - et lidt klodset API som godt kan give meget kode Jeg er forbløffet over at ODBC kald ikke bruges mere i C/C++. Der er kommet nyere teknologi i form af OLE DB og ADO. Men de har mindre support fra database leverandørerne og kræver kommercielle compilere. Det er almindeligt kendt at OLE DB / ADO performer bedre end ODBC i VBA/VBS/VB. Men jeg er ikke overbevist om at det samme gælder i C/C++. Min hypotese er at OLE DB er designet og dermed optimeret til at skulle bruges i VBA/VBS/VB, mens ODBC er designet og dermed optimeret til at skulle bruges i C/C++, og at det er X laget der gør ODBC langsomt. Men jeg kan ikke bevise min hypotese. Eksempler Eksemplerne vil bruge denne meget simple database: CREATE TABLE t1 ( f1 INTEGER; f2 VARCHAR(50), PRIMARY KEY(f1) ); Eksemplerne vil være i C d.v.s. kunne bruges både i C og C++. Eksemplerne er meget simple, men bør nemt kunne udvides til noget mere avanceret udfra dokumentationen på ovennævnte link. Eksemplerne er testet mod en Access database, men ODBC er som sagt database uafhængig. For at bruge MySQL skal man kun ændre DSN eller connection string. Forespørgsel Med DSN: #include <stdio.h> #include <stdlib.h>

/* nødvendige header filer for at bruge ODBC */ #include <windows.h> #include <sql.h> #include <sqlext.h> /* * åben connection til: * DSN = "TestMSAccess" * username = "" (bliver opfattet som defaut "Admin" i Access) * password = "" */ char *dsn = "TestMSAccess"; char *un = ""; char *pw = ""; int main() /* ODBC environment */ SQLHENV Environment; /* ODBC connection */ SQLHDBC DataBaseConnect; /* ODBC statement */ SQLHSTMT stmt; /* ODBC return status */ SQLRETURN stat; /* query */ char *sqlstr = "SELECT * FROM T1"; /* integer værdi (f1) */ int i; /* string værdi (f2) */ char s[50]; /* længder af integer og string værdi */ int il,sl; /* alloker environment = initialiser ODBC */ stat = SQLAllocEnv(&Environment); printf("error in AllocEnv\n"); /* connect til database */ stat = SQLAllocConnect(Environment,&DataBaseConnect); printf("error in AllocConnect\n"); stat = SQLConnect(DataBaseConnect, (SQLCHAR *)dsn,(sqlsmallint)strlen(dsn), (SQLCHAR *)un,(sqlsmallint)strlen(un), (SQLCHAR *)pw,(sqlsmallint)strlen(pw)); printf("error in Connect\n"); /* alloker statement */ stat = SQLAllocStmt(DataBaseConnect,&stmt);

printf("error in AllocStmt\n"); /* udfør statement */ stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,strlen(sqlstr)); printf("error in ExecDirect\n"); /* bind kolonne 1 (f1) til i (integer værdi) og kolonne 2 (f2) til sv (string værdi) */ stat = SQLBindCol(stmt,1,SQL_C_LONG,&i,sizeof(i),(SQLINTEGER *)&il); printf("error in BindCol\n"); stat = SQLBindCol(stmt,2,SQL_C_CHAR,s,sizeof(s),(SQLINTEGER *)&sl); printf("error in BindCol\n"); /* hent alle rækker */ for(;;) stat = SQLFetch(stmt); break; s[sl] = '\0'; printf("%d %s\n",i,s); /* luk cursor så statement kan genbruges til ny forespørgsel */ SQLCloseCursor(stmt); /* frigør statement */ SQLFreeStmt(stmt,SQL_DROP); /* disconnect og frigør connection */ SQLDisconnect(DataBaseConnect); SQLFreeConnect(DataBaseConnect); /* frigør environment */ SQLFreeEnv(Environment); return 0; Uden DSN: #include <stdio.h> #include <stdlib.h> /* nødvendige header filer for at bruge ODBC */ #include <windows.h> #include <sql.h> #include <sqlext.h>

/* * åben connection til: * driver = "Microsoft Access Driver (*.mdb)" * database = "D:\\Database\\MSAccess\\Test.mdb" * username = "Admin" * password = "" */ char *constr = "Driver=Microsoft Access Driver (*.mdb);dbq=d:\\database\\msaccess\\test.mdb;uid=admin;pwd=;"; int main() /* ODBC environment */ SQLHENV Environment; /* ODBC connection */ SQLHDBC DataBaseConnect; /* ODBC statement */ SQLHSTMT stmt; /* ODBC return status */ SQLRETURN stat; /* returned connection string */ char outconstr[1024]; /* length of returned connection string */ int outconlen; /* query */ char *sqlstr = "SELECT * FROM T1"; /* integer værdi (f1) */ int i; /* string værdi (f2) */ char s[50]; /* længder af integer og string værdi */ int il,sl; /* alloker environment = initialiser ODBC */ stat = SQLAllocEnv(&Environment); printf("error in AllocEnv\n"); /* connect til database */ stat = SQLAllocConnect(Environment,&DataBaseConnect); printf("error in AllocConnect\n"); stat = SQLDriverConnect(DataBaseConnect,NULL, (SQLCHAR *)constr,(sqlsmallint)strlen(constr), (SQLCHAR *)outconstr, (SQLSMALLINT)sizeof(outconstr), (SQLSMALLINT *)&outconlen,sql_driver_complete); printf("error in Connect\n"); /* alloker statement */ stat = SQLAllocStmt(DataBaseConnect,&stmt);

printf("error in AllocStmt\n"); /* udfør statement */ stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,strlen(sqlstr)); printf("error in ExecDirect\n"); /* bind kolonne 1 (f1) til i (integer værdi) og kolonne 2 (f2) til sv (string værdi) */ stat = SQLBindCol(stmt,1,SQL_C_LONG,&i,sizeof(i),(SQLINTEGER *)&il); printf("error in BindCol\n"); stat = SQLBindCol(stmt,2,SQL_C_CHAR,s,sizeof(s),(SQLINTEGER *)&sl); printf("error in BindCol\n"); /* hent alle rækker */ for(;;) stat = SQLFetch(stmt); break; s[sl] = '\0'; printf("%d %s\n",i,s); /* luk cursor så statement kan genbruges til ny forespørgsel */ SQLCloseCursor(stmt); /* frigør statement */ SQLFreeStmt(stmt,SQL_DROP); /* disconnect og frigør connection */ SQLDisconnect(DataBaseConnect); SQLFreeConnect(DataBaseConnect); /* frigør environment */ SQLFreeEnv(Environment); return 0; Opdatering Med DSN: #include <stdio.h> #include <stdlib.h> /* nødvendige header filer for at bruge ODBC */ #include <windows.h>

#include <sql.h> #include <sqlext.h> /* * åben connection til: * DSN = "TestMSAccess" * username = "" (bliver opfattet som defaut "Admin" i Access) * password = "" */ char *dsn = "TestMSAccess"; char *un = ""; char *pw = ""; int main() /* ODBC environment */ SQLHENV Environment; /* ODBC connection */ SQLHDBC DataBaseConnect; /* ODBC statement */ SQLHSTMT stmt; /* ODBC return status */ SQLRETURN stat; /* insert */ char sqlstr[200]; /* counter */ int i; /* alloker environment = initialiser ODBC */ stat = SQLAllocEnv(&Environment); printf("error in AllocEnv\n"); /* connect til database */ stat = SQLAllocConnect(Environment,&DataBaseConnect); printf("error in AllocConnect\n"); stat = SQLConnect(DataBaseConnect, (SQLCHAR *)dsn,(sqlsmallint)strlen(dsn), (SQLCHAR *)un,(sqlsmallint)strlen(un), (SQLCHAR *)pw,(sqlsmallint)strlen(pw)); printf("error in Connect\n"); /* alloker statement */ stat = SQLAllocStmt(DataBaseConnect,&stmt); printf("error in AllocStmt\n"); /* indsæt 10 rækker */ for(i=0;i<10;i++)

sprintf(sqlstr,"insert INTO t1 VALUES(%d,'%s')",100+i,"Dette er en test"); stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,strlen(sqlstr)); printf("error in ExecDirect\n"); /* frigør statement */ SQLFreeStmt(stmt,SQL_DROP); /* disconnect og frigør connection */ SQLDisconnect(DataBaseConnect); SQLFreeConnect(DataBaseConnect); /* frigør environment */ SQLFreeEnv(Environment); return 0; Uden DSN: #include <stdio.h> #include <stdlib.h> /* nødvendige header filer for at bruge ODBC */ #include <windows.h> #include <sql.h> #include <sqlext.h> /* * åben connection til: * driver = "Microsoft Access Driver (*.mdb)" * database = "D:\\Database\\MSAccess\\Test.mdb" * username = "Admin" * password = "" */ char *constr = "Driver=Microsoft Access Driver (*.mdb);dbq=d:\\database\\msaccess\\test.mdb;uid=admin;pwd=;"; int main() /* ODBC environment */ SQLHENV Environment; /* ODBC connection */ SQLHDBC DataBaseConnect; /* ODBC statement */ SQLHSTMT stmt; /* ODBC return status */ SQLRETURN stat; /* returned connection string */ char outconstr[1024];

/* length of returned connection string */ int outconlen; /* insert */ char sqlstr[200]; /* counter */ int i; /* alloker environment = initialiser ODBC */ stat = SQLAllocEnv(&Environment); printf("error in AllocEnv\n"); /* connect til database */ stat = SQLAllocConnect(Environment,&DataBaseConnect); printf("error in AllocConnect\n"); stat = SQLDriverConnect(DataBaseConnect,NULL, (SQLCHAR *)constr,(sqlsmallint)strlen(constr), (SQLCHAR *)outconstr, (SQLSMALLINT)sizeof(outconstr), (SQLSMALLINT *)&outconlen,sql_driver_complete); printf("error in Connect\n"); /* alloker statement */ stat = SQLAllocStmt(DataBaseConnect,&stmt); printf("error in AllocStmt\n"); /* indsæt 10 rækker */ for(i=0;i<10;i++) sprintf(sqlstr,"insert INTO t1 VALUES(%d,'%s')",100+i,"Dette er en test"); stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,strlen(sqlstr)); printf("error in ExecDirect\n"); /* frigør statement */ SQLFreeStmt(stmt,SQL_DROP); /* disconnect og frigør connection */ SQLDisconnect(DataBaseConnect); SQLFreeConnect(DataBaseConnect); /* frigør environment */ SQLFreeEnv(Environment); return 0;

Build Nedenfor angives hvordan man builder command line med forskellige compilere. Hvis man bruger en IDE skal man lave noget tilsvarende. Microsoft VC++: cl query.c odbc32.lib cl insert.c odbc32.lib Borland C++ Builder: bcc32 query.c \borland\bcc55\lib\psdk\odbc32.lib bcc32 insert.c \borland\bcc55\lib\psdk\odbc32.lib (den gratis command line BCB 5.5 kommer tilsyneladende ikke med ODBC32.LIB, men den kan man få ved at installere Microsoft Platform SDK - og jeg er sikker på at betalings versionerne har den) GCC/MinGW32: gcc query.c -lodbc32 -o query.exe gcc insert.c -lodbc32 -o insert.exe Fejl Hvis man får en fejl på en SQL sætning og gerne vil vide årsagen kan man: int errptr,msglen; char state[5],msg[1000];... SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, (SQLCHAR*)state, (SQLINTEGER*)&errptr, (SQLCHAR*)msg, sizeof(msg), (SQLSMALLINT*)&msglen); printf("error text = %s\n", msg);' Kommentar af mathiash d. 01. Jan 2006 1 Kommentar af looppen d. 09. Aug 2005 2

Kommentar af brhino d. 26. Mar 2004 3