Visual C++ : Verbindung mit SQL Datenbank herstellen und query starten...



  • So hallo erstmal 🙂
    Hab folgendes Problem:

    Ich will mit Visual C++ (Express Edition 2008) ein Programm schreiben, dass sich mit einer Microsoft SQL Server Datenbank verbindet und eine query startet und die zurückgegebenen Werte in eine Tabelle speichert.

    Da ich eig. totaler C++ Noob bin (bin eher der Delphi-Typ) stoße ich gerade iw an meine Grenzen.
    Hab gelesen,dass man eine Verbindung per ODBC / OLE DB herstellen kann, doch wie genau das funktionieren soll weiss ich nicht...
    Auch Codeschnipsel wie:

    Driver={SQL Server};Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;
    

    helfen mir nicht weiter, da mir anscheinen nen #include fehlt...

    habs übrigens auch mit DTL versucht... aber iw meckert er immer rum bei

    using namespace "DTL"
    

    Frust pur....

    Wäre echt super wenn mir jmd. erklären könnte wie ich da drangehen soll 🙂



  • Verwendest Du DotNet mit C++/CLI? Wenn ja dann schau' Dir mal diesen Schnipsel an.

    #include "stdafx.h"
    
    using namespace System;
    using namespace System::Data;
    using namespace System::Data::Common;
    using namespace System::Data::SqlClient;
    
    int main(array<System::String ^> ^args)
    {
    
        SqlConnection ^cnc = gcnew SqlClient::SqlConnection("Data Source=<server>;Initial Catalog=<database>;User ID=*******;Password=*******");
        DataSet ^set = gcnew DataSet("myData");
        DataAdapter ^adp = gcnew SqlDataAdapter("SELECT * FROM Personal", cnc);
        adp->Fill(set);
    
        Console::WriteLine(L"Hello World");  
        return 0;
    }
    


  • yey! Vielen Dank 🙂

    Data Source ist doch meine Serveradresse und Initial Catalog meine Datenbank oder? Werde jetzt mal ein bisschen weiterschreiben 🙂
    Vielen lieben Dank nochmal!



  • Verstehe ich richtig, dass dieser "schnipsel" bei einer erfolgreichen Verbindung "Hello World" in der Konsole anzeigen sollte?
    Also entweder sind meine Daten falsch die ich eingegeben habe, oder ich habe was übersehen.
    Btw. was bedeutet das hier -> gcnew DataSet("myData"); also das "myData"??
    Vielen Dank nochmal 🙂



  • Ich habe das einfach in ein leeres Projekttemplate reinkopiert, "Hello world" war von diesem Template angelegt worden. Einfach entfernen.
    myData ist der Name des Datasets, wahrscheinlich unwichtig. Du solltest im Dataset jetzt eine Tabelle haben, die beispielsweise über eine BindingSource mit einem Control wie Datagridview verbunden werden kann.
    Falls keine Daten drin sind mal prüfen ob die Verbindung erst noch geöffnet werden muss. Du kannst ein Breakpoint auf das return machen und dann über Debug->Locals zur Diagnostik auswerten.



  • argh ich bekomme das wohl nie hin 😞
    Folgender Fehler beim debuggen ->

    A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
    

    xD... Problem solved-> es lag hier drann

    adp->Fill(set);
    

    [Zum Dataset: Ich habe eine "Windows Forms Application" mit einer DataGridView. Dort kann ich das Dataset eingeben, doch meine Problem, wo muss ich das DataSet ankündigen?



  • Hmh, sieht so aus, dass in VS 2008 kein C++/CLI-Support für strongtyped datasets vorhanden ist. Ist ärgerlich, weil es viele Sachen vereinfacht.
    Ich habe jetzt ein Dataset auf das Formular gezogen (Member des Forms) und es als dsMain benannt. Dazu eine BindingSource (bndMain) und im Code diese verknüpft:

    SqlConnection ^cnc = gcnew SqlClient::SqlConnection("Data Source=<server>;Initial Catalog=<database>;User ID=*******;Password=*******");
        DataAdapter ^adp = gcnew SqlDataAdapter("SELECT * FROM Personal", cnc);
        adp->Fill(dsMain);
        bndMain->DataSource = dsMain;
        bndMain->DataMember = dsMain->Tables[0]->TableName;
        grdMain->DataSource = bndMain;
    

    Dann habe ich im Datagridview Spalten eingefügt und im DataPropertyName die entsprechenden Spaltennamen der DB-Tabelle eingetragen. Und er zeigt die Daten an.



  • .\new4.cpp(17) : error C2065: 'adp' : undeclared identifier
    .\new4.cpp(17) : error C2227: left of '->Fill' must point to class/struct/union/generic type
            type is ''unknown-type''
    .\new4.cpp(17) : error C2065: 'dsMain' : undeclared identifier
    .\new4.cpp(18) : error C2065: 'bndMain' : undeclared identifier
    .\new4.cpp(18) : error C2227: left of '->DataSource' must point to class/struct/union/generic type
            type is ''unknown-type''
    .\new4.cpp(18) : error C2065: 'dsMain' : undeclared identifier
    .\new4.cpp(19) : error C2065: 'bndMain' : undeclared identifier
    .\new4.cpp(19) : error C2227: left of '->DataMember' must point to class/struct/union/generic type
            type is ''unknown-type''
    .\new4.cpp(19) : error C2065: 'dsMain' : undeclared identifier
    .\new4.cpp(19) : error C2227: left of '->Tables' must point to class/struct/union/generic type
            type is ''unknown-type''
    .\new4.cpp(19) : error C2227: left of '->TableName' must point to class/struct/union/generic type
    .\new4.cpp(20) : error C2065: 'grdMain' : undeclared identifier
    .\new4.cpp(20) : error C2227: left of '->DataSource' must point to class/struct/union/generic type
            type is ''unknown-type''
    .\new4.cpp(20) : error C2065: 'bndMain' : undeclared identifier
    

    Was habe ich bloß angestellt?..... 😮
    ... hab per Zufall nen DataSet erstellt.... aber weiss nicht mehr wie...
    mit ner schönen erklärung wärst du mein Retter 😉



  • Na, mache es doch rückgängig. Funktioniert der Formeditor noch? Vllt neues Form bauen und dort testen.



  • so... bin jetzt so ->

    int main(array<System::String ^> ^args)
    {
    
        SqlConnection ^cnc = gcnew SqlClient::SqlConnection("Data Source=************+;Initial Catalog=dpf;User ID=*******;Password=*****"); 
        DataAdapter ^adp = gcnew SqlDataAdapter("SELECT * FROM ************", cnc); 
    
    	DataSet ^dsMain = gcnew DataSet;
    	BindingSource ^bndMain = gcnew BindingSource;
    	DataGridView ^grdMain = gcnew DataGridView;
    
    //	adp->Fill(dsMain); 
        bndMain->DataSource = dsMain; 
        bndMain->DataMember = dsMain->Tables[0]->TableName; 
        grdMain->DataSource = bndMain;
    

    weit....

    Fehler die jetzt auftauchen.... ->

    A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
    A first chance exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll
    An unhandled exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll
    
    Additional information: Cannot find table 0.
    


  • Mit adp->Fill(dsMain); werden die Daten vom Server abgerufen und in das DataSet als Tabelle eingetragen. Das Dataset ist nach der Konstruktion leer, durch das Füllen entsteht dsMain->Tables[0]. Warum hast das auskommentiert? Gibt es Fehler? Ist das SQL fehlerhaft?



  • Spätestens wenn ich

    adp->Fill(dsMain);
    

    wieder zugänglich mache bekomme ich das hier ->

    A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
    


  • Dann kapsele es doch in einem try catch und analysiere das Fehlerobjekt. Möglicherweise ist das SQL fehlerhaft.



  • So... Fehler sind weg... aber die Daten laden nicht in der Grid....
    hier der Quelltext...

    #include "Form1.h"
    
    using namespace Clean;
    using namespace System; 
    using namespace System::Data; 
    using namespace System::Data::Common; 
    using namespace System::Data::SqlClient; 
    
    [STAThreadAttribute]
    int main(array<System::String ^> ^args)
    {
     //SetCompatibleTextRenderingDefault(true);
    	// Enabling Windows XP visual effects before any controls are created
    	Application::EnableVisualStyles();
    	Application::SetCompatibleTextRenderingDefault(false); 
    
    	// Create the main window and run it
    
    	SqlConnection ^cnc = gcnew SqlClient::SqlConnection("Data Source=ne-sql-02[b]\[/b]sql02;Initial Catalog=DPF;User ID=*****;Password=*******"); 
        DataAdapter ^adp = gcnew SqlDataAdapter("SELECT CLID FROM [b]PCDOWN[/b].TE_DPF_ELISEP_INTERIM_TEST ", cnc);  
    	DataSet ^dataSet1 = gcnew DataSet;
    	BindingSource ^bndMain = gcnew BindingSource;
    	DataGridView ^grdMain = gcnew DataGridView;
    
        adp->Fill(dataSet1); 
    	bndMain->DataSource = dataSet1; 
        bndMain->DataMember = dataSet1->Tables[0]->TableName; 
        grdMain->DataSource = bndMain; 
    
    	Application::Run(gcnew Form1());
    
    	return 0;
    }
    


  • witte schrieb:

    Dann habe ich im Datagridview Spalten eingefügt und im DataPropertyName die entsprechenden Spaltennamen der DB-Tabelle eingetragen. Und er zeigt die Daten an.



  • Also... habe eben ein Select * auf die Tabelle gemacht... und er schien auch etwas zu verarbeiten... dauerte etwa 5min bis das Programm gestartet war... Ergebnis : 0 ... hab auch DataPropertyName richtig bennant... glaube ich zumindest...

    Hier einige Screenshots... vll findest du ja den Fehler 🙂

    Column1
    grdMain
    Form
    DataSet
    BindingSource



  • Ich habe jetzt nur 5 Sekunden drauf geschaut, aber muesste DataSource im bndMain nicht dsMain sein? Arbeitest Du mit 2 DataSets?



  • also, ich kann nur DataSet1 oder Form1 als DataSource eingeben...
    In der Tat heisst das 1 DataSet = dsMain aber iw erscheint auf der Form immernoch der name DataSet1 und in der DataSource von bndMain erschein eben nur DataSet1 als DataSet. Und ich arbeite nur mit einem DataSet
    😞

    Edit*: hab dsMain überall zu DataSet1 übergeschrieben... sollte ja eigentlich so auch gehen... Erfolg = nada....
    Scheinbar ist jetzt Imageshack down... argh... 😞



  • Nach dem "Erfolg" letztens war ich zuversichtlich, dass es jetzt klappen würde-.-
    aber anscheinend ist da doch noch irgendwo der Wurm drinn... 😞

    // CRAP.cpp : main project file.
    
    #include "stdafx.h"
    #include "Form1.h"
    
    using namespace CRAP;
    using namespace System;
    using namespace System::Data;
    using namespace System::Data::Common;
    using namespace System::Data::SqlClient;
    
    [STAThreadAttribute]
    int main(array<System::String ^> ^args)
    {
    // Enabling Windows XP visual effects before any controls are created
    	Application::EnableVisualStyles();
    	Application::SetCompatibleTextRenderingDefault(false); 
    
    	SqlConnection ^cnc = gcnew SqlClient::SqlConnection("Data Source=ne-sql-02\\sql02;Initial Catalog=DPF;User ID=----------;Password=---------"); 
       DataSet ^dataSet1 = gcnew DataSet("dataSet1");
    	DataAdapter ^adp = gcnew SqlDataAdapter("SELECT CLID FROM PCDOWN.TE_DPF_ELISEP_INTERIM_TEST ", cnc);  
       adp->Fill(dataSet1);
       BindingSource ^bindingSource1 = gcnew BindingSource;
       bindingSource1->DataSource = dataSet1;
       bindingSource1->DataMember = dataSet1->Tables[0]->TableName;
       DataGridView ^dataGridView1 = gcnew DataGridView;
       dataGridView1->DataSource =  bindingSource1;
    
    	// Create the main window and run it
    	Application::Run(gcnew Form1());
    
    	return 0;
    }
    


  • Hi, warum legst Du noch ein DatagridView an?

    DataGridView ^dataGridView1 = gcnew DataGridView;
    

    Du musst doch das nehmen, welches Du mit dem Designer angelegt hast.


Anmelden zum Antworten