Avatar billede bumle90 Nybegynder
21. januar 2004 - 22:53 Der er 34 kommentarer og
1 løsning

Oprette tilgang til DB via ADO uden at lave en DSN

Er det muligt i VC++?
Altså bare at sætte sin connectstring til at pege direkte på databasen...
Og er det både muligt i Access og MS-SQL-Server?
Avatar billede borrisholt Novice
21. januar 2004 - 22:59 #1
Det her er til C++ builder, men burde give dig en idt til at komme videre ...
http://borrishotl.com/eksperten/ADOEksempel.zip

Jens B
Avatar billede borrisholt Novice
21. januar 2004 - 22:59 #2
Avatar billede bumle90 Nybegynder
21. januar 2004 - 23:05 #3
øhhh der er ca. 30.000 koders linie der :)
Hvor finder jeg det der er interresant....Jeg har ikke rigtig brugt den builder før....
Avatar billede bumle90 Nybegynder
21. januar 2004 - 23:07 #4
og det er noget Delphi halløj det der ?
Avatar billede arne_v Ekspert
22. januar 2004 - 20:00 #5
Her kommer et simpelt Access eksempel.

Med DSN:

#include <stdio.h>
#include <stdlib.h>

#include <windows.h>
#include <sql.h>
#include <sqlext.h>

char* dsn = "TestMSAccess";
char* un = "";
char* pw = "";
char* sqlstr = "SELECT * FROM T1";

int main(int argc, char *argv[])
{
  SQLHENV Environment;
  SQLHDBC DataBaseConnect;
  SQLHSTMT stmt;
  SQLRETURN stat;
  int i,il,sl;
  char s[10];
  stat = SQLAllocEnv(&Environment);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in AllocEnv\n");
  stat = SQLAllocConnect(Environment,&DataBaseConnect);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in AllocConnect\n");
  stat = SQLConnect(DataBaseConnect,
                    (SQLCHAR *)dsn,(SQLSMALLINT)strlen(dsn),
                    (SQLCHAR *)un,(SQLSMALLINT)strlen(un),
                    (SQLCHAR *)pw,(SQLSMALLINT)strlen(pw));
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in Connect\n");
  stat = SQLAllocStmt(DataBaseConnect,&stmt);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in AllocStmt\n");
  stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,strlen(sqlstr));
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in ExecDirect\n");
  stat = SQLBindCol(stmt,1,SQL_C_LONG,&i,sizeof(i),(SQLINTEGER *)&il);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in BindCol\n");
  stat = SQLBindCol(stmt,2,SQL_C_CHAR,s,sizeof(s),(SQLINTEGER *)&sl);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in BindCol\n");
  for(;;) {
    stat = SQLFetch(stmt);
    if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) break;
    s[sl] = '\0';
    printf("%d %s\n",i,s);
  }
  SQLFreeStmt(stmt,SQL_DROP);
  SQLDisconnect(DataBaseConnect);
  SQLFreeConnect(DataBaseConnect);
  SQLFreeEnv(Environment); 
  return 0;
}

Uden DSN:

#include <stdio.h>
#include <stdlib.h>

#include <windows.h>
#include <sql.h>
#include <sqlext.h>

char* constr =  "Driver={Microsoft Access Driver (*.mdb)};Dbq=D:\\Database\\MSAccess\\Test.mdb;Uid=Admin;Pwd=;";
char* sqlstr = "SELECT * FROM T1";

int main(int argc, char *argv[])
{
  SQLHENV Environment;
  SQLHDBC DataBaseConnect;
  SQLHSTMT stmt;
  SQLRETURN stat;
  int i,il,sl,outconlen;
  char s[10],outconstr[1024];
  stat = SQLAllocEnv(&Environment);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in AllocEnv\n");
  stat = SQLAllocConnect(Environment,&DataBaseConnect);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in AllocConnect\n");
  stat = SQLDriverConnect(DataBaseConnect,NULL,
                    (SQLCHAR *)constr,(SQLSMALLINT)strlen(constr),
                    (SQLCHAR *)outconstr, (SQLSMALLINT)sizeof(outconstr),
                    (SQLSMALLINT *)&outconlen,SQL_DRIVER_COMPLETE);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in Connect\n");
  stat = SQLAllocStmt(DataBaseConnect,&stmt);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in AllocStmt\n");
  stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,strlen(sqlstr));
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in ExecDirect\n");
  stat = SQLBindCol(stmt,1,SQL_C_LONG,&i,sizeof(i),(SQLINTEGER *)&il);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in BindCol\n");
  stat = SQLBindCol(stmt,2,SQL_C_CHAR,s,sizeof(s),(SQLINTEGER *)&sl);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in BindCol\n");
  for(;;) {
    stat = SQLFetch(stmt);
    if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) break;
    s[sl] = '\0';
    printf("%d %s\n",i,s);
  }
  SQLFreeStmt(stmt,SQL_DROP);
  SQLDisconnect(DataBaseConnect);
  SQLFreeConnect(DataBaseConnect);
  SQLFreeEnv(Environment); 
  return 0;
}
Avatar billede bumle90 Nybegynder
22. januar 2004 - 22:07 #6
kanon :]
Hvor finder du dog den info henne...eller er du bare så vild at du lige sætte dig ned og fyrer den kode af?
Avatar billede arne_v Ekspert
22. januar 2004 - 22:10 #7
Eksemplet med DSN havde jeg liggende.

Og det var ikke så svært at finde lidt info om SQLDriverConnect kaldet som
skal bruges til DSN-less connection.
Avatar billede bumle90 Nybegynder
22. januar 2004 - 22:31 #8
oki...Jeg forstår ikke helt hvor der bliver lagt værdier ned i resultsættet...
Og hvordan kører jeg til EOF på recordsæt....Og bestemmer hvilken att. jeg vil kigge på ?
Avatar billede arne_v Ekspert
22. januar 2004 - 22:35 #9
// loop uendelig
for(;;) {
    // hent række
    stat = SQLFetch(stmt);
    // hop ud af lykke hvis ikke flere data
    if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) break;
Avatar billede arne_v Ekspert
22. januar 2004 - 22:37 #10
// gem kolonne 1 i variablen 'i'
  stat = SQLBindCol(stmt,1,SQL_C_LONG,&i,sizeof(i),(SQLINTEGER *)&il);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in BindCol\n");
  // gem kolonne 2 i variablen 's' (og længden i variablen sl)
  stat = SQLBindCol(stmt,2,SQL_C_CHAR,s,sizeof(s),(SQLINTEGER *)&sl);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) printf("Error in BindCol\n");
Avatar billede arne_v Ekspert
22. januar 2004 - 22:38 #11
Tabellen har 2 kolonner - en INTEGER og en VARCHAR(50)
Avatar billede bumle90 Nybegynder
22. januar 2004 - 22:38 #12
mmmm ja oki..nu virker det...Gjorde det bare ikke før jeg prøvede...
Men hvis jeg skal vælge en attribut..Hvor gør jeg det henne?
Avatar billede bumle90 Nybegynder
22. januar 2004 - 22:40 #13
ja oki...
Avatar billede arne_v Ekspert
22. januar 2004 - 22:43 #14
Iøvrigt så er det her ren ODBC - ikke ADO / OLE DB.
Avatar billede bumle90 Nybegynder
22. januar 2004 - 22:45 #15
nej...oki.
Ville der være fordele i hastighed osv. ved at bruge en ADO?
Den er jo en smule nyere....og OL DB også...Men ADO bruger OLE DB så vidt jeg ved ikke sandt?
Avatar billede arne_v Ekspert
22. januar 2004 - 22:49 #16
ADO er en ActiveX overbygning på OLE DB.

OLE DB skulle være hurtigere end ODBC ihvertfald til Microsoft databaser.

Jeg har aldrig leget med OLE DB.

Muligvis skal man også bruge MFC eller ATL for at bruge OLE DB fra C++.

Noget som jeg aldrig har dyrket.
Avatar billede bumle90 Nybegynder
22. januar 2004 - 22:56 #17
Nej...jeg tror også gerne jeg vil holde mig fra MFC her i første omgang....
Vil gerne holde mig til ren C++ og rene API kald...
MFC roder det hele lidt sammen synes jeg...
Fx. også med grafik, det kan man jo også lave med API-kald istedet for MFC...Selvom det jo måske muligvis nok er en smule lettere i MFC?
Avatar billede bumle90 Nybegynder
22. januar 2004 - 23:00 #18
Der er noget andet jeg har undret mig over.
I princippet er det her jo det samme

char* navn;
funktionsnavn(navn);

char navn[10];
funktionsnavn(navn);

char navn[]={0};
funktionsnavn(navn);

char navn[]={"en tekst};
funktionsnavn(navn);

Men af en eller anden årsag går programmet ned hvis man vælge at kalde funktionen, fx. BindCol el. Sprintf med en forkert "streng type", somregel char*
Hvorfor går det galt? Det er jo en pointer til en char ligegyldigt hvad ik?
Avatar billede arne_v Ekspert
22. januar 2004 - 23:05 #19
char* navn; // kald med pointer som peger på ingenting
funktionsnavn(navn);

char navn[10]; // kald med pointer som peger på 10 chars
funktionsnavn(navn);

char navn[]={0}; // kald med pointer som peger på 1 char
funktionsnavn(navn);

char navn[]={"en tekst}; // kald med pointer som peger på 9 chars
funktionsnavn(navn);
Avatar billede bumle90 Nybegynder
23. januar 2004 - 00:39 #20
Hvad hvis jeg skal lægge noget i databasen. Jeg har prøvet at udskifte SQL strengen med en INSERT INTO, men enten kommer den med en "Error in ExecDirect" da følgende linie går galt
  stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,strlen(sqlstr));
Er det meningen man skal gøre det på en anden måde?
Avatar billede arne_v Ekspert
23. januar 2004 - 08:15 #21
Hm.

Jeg mener bestemt at jeg har brugt ExecDirect til at lave INSERT med.
Avatar billede bumle90 Nybegynder
23. januar 2004 - 11:45 #22
Skal man binde en kolonne først før man bruger ExecDirect så eller hvad?
Avatar billede arne_v Ekspert
23. januar 2004 - 12:05 #23
Nej - man bruger bare:
  INSERT INTO tabel (felt1, felt2, felt3) VALUE(1, 101, 'ABC');
Avatar billede arne_v Ekspert
23. januar 2004 - 12:05 #24
VALUES

(med S)

sorry
Avatar billede bumle90 Nybegynder
23. januar 2004 - 12:27 #25
ja oki...jeg får godt nok en underlig fejl når jeg prøver...Kan du se hvad jeg gør galt?

/******OPBYGNING AF DB(access)******
tabel:filliste
initialer(text),filnavn(text),ip(text)
****************************/

#include "stdafx.h"
#include <iostream>

using namespace std;

#include <stdlib.h>

#include <windows.h>
#include <sql.h>
#include <sqlext.h>

char* dsn = "Filsys";
char* un = "";
char* pw = "";
char* sqlstr = "INSERT INTO filliste(initialer,filnavn,ip) VALUES ('nr1','nr2','nr3')";


void MakeDBConnect(SQLHENV Environment,SQLHDBC DataBaseConnect,SQLRETURN stat,SQLHSTMT stmt)
{
/*****************************************/
  stat = SQLAllocEnv(&Environment);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in AllocEnv" << endl;
/*****************************************/ 
  stat = SQLAllocConnect(Environment,&DataBaseConnect);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in AllocConnect" << endl;
/*****************************************/ 
  stat = SQLConnect(DataBaseConnect,
                    (SQLCHAR *)dsn,strlen(dsn),
                    (SQLCHAR *)un,strlen(un),
                    (SQLCHAR *)pw,strlen(pw));
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in Connect" << endl;
/*****************************************/ 
  stat = SQLAllocStmt(DataBaseConnect,&stmt);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in AllocStmt" << endl;
/*****************************************/
}
void insertDB(SQLRETURN stat,SQLHSTMT stmt/*,char* sqlstr*/)
{
  stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,SQL_NTS);
  if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in ExecDirect" << endl;

  SQLFreeStmt(stmt,SQL_DROP);
}
void freeDB(SQLHENV Environment,SQLHDBC DataBaseConnect)
{
  SQLDisconnect(DataBaseConnect);
  SQLFreeConnect(DataBaseConnect);
  SQLFreeEnv(Environment); 
}

int main(int argc, char *argv[])
{
SQLHENV Environment;
SQLHDBC DataBaseConnect;
SQLHSTMT stmt;
SQLRETURN stat;
//int il,sl;
/*char initialer[20];
char filnavn[20];
char ip[20];
*/
MakeDBConnect(Environment,DataBaseConnect,stat,stmt);
insertDB(stat,stmt/*,sqlstr*/);
freeDB(Environment,DataBaseConnect);
  return 0;
}
Avatar billede arne_v Ekspert
23. januar 2004 - 12:41 #26
Skriv stat ud og find værdien i .H filen !

Det bør fortælle mere præcist hvad fejlen er.
Avatar billede bumle90 Nybegynder
23. januar 2004 - 12:42 #27
Det er en runtime fejl som sker når jeg kalder freeDB();
Jeg ved ikke helt hvad der går galt...Måske noget med jeg ikke smider parametrene korrekt rundt..Skal jeg kaste & afsted til funktionen istedet for mon?
Avatar billede arne_v Ekspert
23. januar 2004 - 12:42 #28
Vildt gæt: du har hard coded værdier, hvis de allerede er indsat en gang,
så kan der være noget med primary key og duplicate value.
Avatar billede arne_v Ekspert
23. januar 2004 - 12:43 #29
Ja for pokker - du kalder by value d.v.s. at ændringer nede i
funktionerne forsvinder sporløst.
Avatar billede arne_v Ekspert
23. januar 2004 - 12:54 #30
Der skal nogle * og & ind.
Avatar billede bumle90 Nybegynder
23. januar 2004 - 12:54 #31
oki...du må undskylde men jeg er stadig ikke helt med på hvad jeg så skal sende med og modtage :)
Håber ikke det er for meget besvær, men hvad skal jeg så medsende og modtage af pointere...jeg kager stadig rundt i det nemlig...& el. * el. bare navnet....
Avatar billede bumle90 Nybegynder
23. januar 2004 - 12:56 #32
Og hvad skal jeg oprette dem som i main?
som fx.
SQLHENV Environment;
el
SQLHENV *Environment; ?
Avatar billede arne_v Ekspert
23. januar 2004 - 13:02 #33
SQLHENV Environment;

MakeDBConnect(&Environment,DataBaseConnect,stat,stmt);

freeDB(&Environment,DataBaseConnect);
 
void MakeDBConnect(SQLHENV *Environment,SQLHDBC DataBaseConnect,SQLRETURN stat,SQLHSTMT stmt)

stat = SQLAllocEnv(Environment);

stat = SQLAllocConnect(*Environment,&DataBaseConnect);

void freeDB(SQLHENV *Environment,SQLHDBC DataBaseConnect)

SQLFreeEnv(*Environment); 

skulle få env på plads.

Ligesådan med de andre.
Avatar billede bumle90 Nybegynder
27. januar 2004 - 13:00 #34
Er det sådan at du evt. ku komme med et eksempel :)
Avatar billede arne_v Ekspert
27. januar 2004 - 18:44 #35
(mystisk mit indlæg forsvandt - jeg prøver igen)

Følgende compiler ihvertfald:

#include <iostream>

using namespace std;

#include <stdlib.h>

#include <windows.h>
#include <sql.h>
#include <sqlext.h>

char* dsn = "Filsys";
char* un = "";
char* pw = "";
char* sqlstr = "INSERT INTO filliste(initialer,filnavn,ip) VALUES ('nr1','nr2','nr3')";


void MakeDBConnect(SQLHENV *Environment,SQLHDBC *DataBaseConnect,SQLRETURN *stat,SQLHSTMT *stmt)
{
/*****************************************/
  *stat = SQLAllocEnv(Environment);
  if((*stat!=SQL_SUCCESS)&&(*stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in AllocEnv" << endl;
/*****************************************/ 
  *stat = SQLAllocConnect(*Environment,DataBaseConnect);
  if((*stat!=SQL_SUCCESS)&&(*stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in AllocConnect" << endl;
/*****************************************/ 
  *stat = SQLConnect(*DataBaseConnect,
                    (SQLCHAR *)dsn,strlen(dsn),
                    (SQLCHAR *)un,strlen(un),
                    (SQLCHAR *)pw,strlen(pw));
  if((*stat!=SQL_SUCCESS)&&(*stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in Connect" << endl;
/*****************************************/ 
  *stat = SQLAllocStmt(*DataBaseConnect,stmt);
  if((*stat!=SQL_SUCCESS)&&(*stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in AllocStmt" << endl;
/*****************************************/
}
void insertDB(SQLRETURN *stat,SQLHSTMT *stmt/*,char* sqlstr*/)
{
  *stat = SQLExecDirect(*stmt,(SQLCHAR *)sqlstr,SQL_NTS);
  if((*stat!=SQL_SUCCESS)&&(*stat!=SQL_SUCCESS_WITH_INFO))
      cout << "Error in ExecDirect" << endl;

  SQLFreeStmt(*stmt,SQL_DROP);
}
void freeDB(SQLHENV *Environment,SQLHDBC *DataBaseConnect)
{
  SQLDisconnect(*DataBaseConnect);
  SQLFreeConnect(*DataBaseConnect);
  SQLFreeEnv(*Environment); 
}

int main(int argc, char *argv[])
{
SQLHENV Environment;
SQLHDBC DataBaseConnect;
SQLHSTMT stmt;
SQLRETURN stat;
//int il,sl;
/*char initialer[20];
char filnavn[20];
char ip[20];
*/
MakeDBConnect(&Environment,&DataBaseConnect,&stat,&stmt);
insertDB(&stat,&stmt/*,sqlstr*/);
freeDB(&Environment,&DataBaseConnect);
  return 0;
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester





White paper
Tidsbegrænset kampagne: Overvejer du at udskifte eller tilføje printere i din forretning? Vi kan tilbyde én eller flere maskiner gratis