OLEDB Neue Eingaben werden "Abgeschnitten"



  • Hat das

    //       Für Spalten mit variablen Längen müssen diese 
        //       Felder vor dem Einfügen von Daten initialisiert werden.
    

    nicht irgend etwas zu bedeuten?
    AFAIK musst Du nicht nur "->m_Name" setzen, sondern auch "->m_dwNameLength"...



  • Kannst Du mir da ein Beispiel geben.
    Ich hab das mit dem Initialisieren schon gelesen. Weiß aber nicht
    wo u. wie muss ich "->m_dwNameLenght" einsetzen.
    Habe schon einigeZeit in der MSDN verbracht, aber nichts gefunden.

    Im Code zum einfügen von Daten (aber Wie?)

    void COLEDBView::OnBnClickedButton1()//Einfügen
    {
    	UpdateData(TRUE);
    
    	m_pSet->MoveLast();
    
        m_pSet->m_ID=m_pSet->m_ID+1; 
        strcpy_s(m_pSet->m_Name,m_Name);
    	strcpy_s(m_pSet->m_Vorname,m_Vorname);
    
    	 HRESULT hr=m_pSet->Insert(); 
        if ( hr != S_OK ) 
        { 
            AfxMessageBox("Hat nicht funktioniert"); 
        } 
    
        m_pSet->UpdateAll(); 
    
    	m_ID=m_pSet->m_ID;
    	m_Name=m_pSet->m_Name;
    	m_Vorname=m_pSet->m_Vorname;
    
    	UpdateData(FALSE); 
    
    }
    


  • Okay, ich habe es jetzt kapiert.

    void COLEDBView::OnBnClickedButton1()//Einfügen
    {
    	UpdateData(TRUE);
    
    	m_pSet->MoveLast();
    	m_pSet->m_dwNameLength=255;
    	m_pSet->m_dwVornameLength=255;
    
             m_pSet->m_ID=m_pSet->m_ID+1; 
    	strcpy_s(m_pSet->m_Name,m_Name);
    	strcpy_s(m_pSet->m_Vorname,m_Vorname);
    

    Danke für Deine Hilfe Jochen. (Super)



  • Naja, besser wäre ja:

    strcpy_s(m_pSet->m_Name,m_Name);
    m_pSet->m_dwNameLength= strlen(m_Name);
    


  • Okay, so sieht das schon professioneller aus.

    Danke nochmals.



  • Hallo Community,

    ich möchte diesen Thread nochmal aufgreifen (und auch den hier), da ich ein ähnliches Problem habe. Ich kann wunderbar Datensätze lesen und auch dazwischen navigieren. Beim Insert scheiters dann. hr hat bei mir den Wert DB_E_ERRORSOCCURRED. Mein Accessor sieht wie folgt aus (weitestgehend vom Assistenten generiert):

    // TestSet.h: Schnittstelle der Klasse CTestSet
    //
    
    #pragma once
    
    // Code generiert auf Donnerstag, 7. Januar 2010, 13:30
    
    [
    //#error Sicherheitsproblem: Die Verbindungszeichenfolge enthält möglicherweise ein Kennwort
    // Die Verbindungszeichenfolge enthält möglicherweise einfache Textkennwörter und/oder
    // andere vertrauliche Informationen. Entfernen Sie #error, nachdem Sie die
    // Verbindungszeichenfolge überprüft haben. Sie können das Kennwort
    // in einem anderen Format speichern oder eine andere Benutzerauthentifizierung verwenden.
    db_source(L"Provider=SQLOLEDB.1;Password=XXX;Persist Security Info=True;User ID=sa;Initial Catalog=Test;Data Source=DB_PC\\DB_TEST;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=MyPC;Use Encryption for Data=False;Tag with column collation when possible=False"),
    	db_table(L"dbo.Personal")
    ]
    class CTestSet
    {
    public:
    	[ db_column(1, status=m_dwIDStatus, length=m_dwIDLength) ] LONG m_ID;
    	[ db_column(2, status=m_dwNameStatus, length=m_dwNameLength) ] TCHAR m_Name[51];
    	[ db_column(3, status=m_dwVornameStatus, length=m_dwVornameLength) ] TCHAR m_Vorname[51];
    	[ db_column(4, status=m_dwAlterStatus, length=m_dwAlterLength) ] LONG m_Alter;
    
    	// Folgende vom Assistenten generierte Datenmember enthalten Statuswerte
    	// für die entsprechenden Felder. Sie können
    	// diese Werte als Null-Werte, die von der Datenbank
    	// zurückgegeben werden, oder für vom Compiler ausgegebene Fehlerinformationen verwenden.
    	// Weitere Informationen finden Sie in der Visual C++-Dokumentation unter Datenmember.
    	// Hinweis: Diese Felder müssen vor dem Einfügen von Daten initialisiert werden.
    
    	DBSTATUS m_dwIDStatus;
    	DBSTATUS m_dwNameStatus;
    	DBSTATUS m_dwVornameStatus;
    	DBSTATUS m_dwAlterStatus;
    
    	// Folgende vom Assistenten generierte Datenmember enthalten Längenwerte
    	// für die entsprechenden Felder.
    	// Hinweis: Für Spalten mit variablen Längen müssen diese
    	//       Felder vor dem Einfügen von Daten initialisiert werden.
    
    	DBLENGTH m_dwIDLength;
    	DBLENGTH m_dwNameLength;
    	DBLENGTH m_dwVornameLength;
    	DBLENGTH m_dwAlterLength;
    
    	void GetRowsetProperties(CDBPropSet* pPropSet)
    	{
    		pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
    		pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
    
    		pPropSet->AddProperty(DBPROP_IRowsetChange, true);
    		pPropSet->AddProperty(DBPROP_UPDATABILITY, DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_INSERT | DBPROPVAL_UP_DELETE); 
    	}
    };
    

    Liegt der Fehler im Code oder an der Datenbank?



  • WAS scheitert? Setzt Du auch die Länge koorekt???



  • Jochen Kalmbach schrieb:

    WAS scheitert? Setzt Du auch die Länge koorekt???

    Also, ich hab das so realisiert:

    void CBenutzerNeu::OnBnClickedSafe()
    {
    	// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
    	UpdateData(TRUE);
    	m_pSet->MoveLast();
    
    	m_pSet->m_ID=m_pSet->m_ID+1;
    
    	_tcscpy(m_pSet->m_Name, Name);
    	m_pSet->m_dwNameLength= Name.GetLength()+1;
    
    	_tcscpy(m_pSet->m_Vorname, Vorname);
    	m_pSet->m_dwVornameLength= Vorname.GetLength()+1;
    
    	m_pSet->m_Alter=Alter;
    
    	HRESULT hr=m_pSet->Insert();
    	if (hr != S_OK)
    	{
    		AfxMessageBox(_T("Das Anlegen des neuen Benutzers ist fehlgeschlagen"));
    	}
    	m_pSet->UpdateAll();
    
    	//m_pSet->CloseAll();
    
    }
    

    hr hat immer den Wert DB_E_ERRORSOCCURRED. Dabei sind mir zwei Fragen gekommen:

    1. Muss man die ID incrementieren? Ich dachte immer die DB macht das selbst.
    2. In dem Beispiel von HermannGo ist für den LONG-Wert der ID auch keine Länge belegt worden. Wie verhält es sich mit solchen Datentypen?


  • Mod

    Wenn ID ein Auto-Inc Key ist, dann darfst Du ihn nicht schreiben!
    Der SQL Server will diese ID selbst vergeben.



  • Martin Richter schrieb:

    Wenn ID ein Auto-Inc Key ist, dann darfst Du ihn nicht schreiben!
    Der SQL Server will diese ID selbst vergeben.

    Ja, die ID ist ein auto-increment-key. Wenn ich den Member allerdings mit einem Wert belege, dann scheint das trotzdem zu gehen.
    Zu dem anderen Problem: ich habe jetzt mit dem Assistenten im bestehenden Projekt nochmal eine Accessor-Klasse erstellt. Wenn ich nur Datenbankfelder habe, die aus Zeichenketten bestehen, kann ich in die Datenbank schreiben, habe aber das Problem wie mein Vorposter, dass da was abgeschnitten wird (und zwar immer exakt die Hälfte). Jetzt hab ich ein Unicode-Projekt und auch die Datenfelder sind vom Typ nvarchar(50), der Datentyp des Accessors ist vom Typ TCHAR [51]. Die Länge wird korrekt ermittelt. Setze ich manuell einen anderen Wert dann schlägt die Transaktion fehl (E_FAIL). Das Problem liegt mit Sicherheit daran, dass ja Unicodezeichen zur Darstellung mehr Bytes benötigen. Allerdings weiß ich nicht, wo ich da ansetzen soll.


Anmelden zum Antworten