Wie bring ich Fotoimages in eine SQL Server 2005 Datenbank ?

Anfängerfragen zum Programmieren mit PureBasic.
Velz
Beiträge: 182
Registriert: 18.10.2004 22:20

Re: Wie bring ich Fotoimages in eine SQL Server 2005 Datenbank ?

Beitrag von Velz »

Gibt es irgendwo einen Link oder Hilfe die das mit dem "?" erklärt???

Interessiert mich doch sehr! Ich hätte vermutet dort müsste die Speicheradresse hin...
Win10/64|Ubuntu-Server|Mint WS // Programmiere Datenbankanwendungen und Tools mit PB-5.x und MySQL-5.x unter Win und Linux
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Wie bring ich Fotoimages in eine SQL Server 2005 Datenbank ?

Beitrag von bobobo »

und ich hätte vermutet das pb das bei richtiger Anwendung von alleine macht

http://www.purebasic.fr/english/viewtop ... tabaseblob


--------

ist ja logisch das ein mit ' unzingelter wert auch korrekt in die datenbank eingetragen wird
das ok hat mich auch auf die falsche Fährte geführt

ist wohl doch eher der ODBC-Treiber der hier querhaut. ich habs mal mit MySQL durchgekaut und da wuppt es

also doch ADO ?? Kiffi fragen
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Wie bring ich Fotoimages in eine SQL Server 2005 Datenbank ?

Beitrag von Kiffi »

@Lupo: södele, hier der Code:

Code: Alles auswählen

IncludePath #PB_Compiler_Home + "srod\comateplus\" 
IncludeFile "comateplus.pbi"

EnableExplicit

#adTypeBinary          = 1
#adOpenKeyset          = 1
#adLockOptimistic      = 3
#adSaveCreateOverWrite = 2

Procedure WriteImageToDatabase(ConnectionString.s, Foto_Nummer, Foto_Image.s)
  
  Protected ADODB_Connection.COMateObject  ; Connection-Object
  Protected ADODB_Recordset.COMateObject   ; Recordset-Object
  Protected ADODB_Stream.COMateObject      ; Stream-Object
  Protected *varStreamRead.VARIANT
  
  If FileSize(Foto_Image) < 0
    Debug "File not found: '" + Foto_Image + "'"
    ProcedureReturn
  EndIf
  
  ADODB_Connection = COMate_CreateObject("ADODB.Connection")
  
  If ADODB_Connection 
    
    If ADODB_Connection\Invoke("Open('" + ConnectionString + "')") = #S_OK
      
      ADODB_Stream = COMate_CreateObject("ADODB.Stream")
      
      If ADODB_Stream
        
        ADODB_Stream\SetProperty("Type=" + Str(#adTypeBinary))
        ADODB_Stream\Invoke("Open")
        ADODB_Stream\Invoke("LoadFromFile('" + ReplaceString(Foto_Image, "'", "$0027") + "')")
        
        ADODB_Recordset = COMate_CreateObject("ADODB.Recordset")
        
        If ADODB_Recordset
          
          If ADODB_Recordset\Invoke("Open('SELECT Foto_Nummer, Foto_Image FROM gamepics Where 1=2', " + Str(ADODB_Connection) + " As COMateObject, " + Str(#adOpenKeyset) + ", " + Str(#adLockOptimistic) + ")") = #S_OK
            
            ADODB_Recordset\Invoke("AddNew")
            
            ADODB_Recordset\SetProperty("Fields('Foto_Nummer')\Value=" + Str(Foto_Nummer))
            
            *varStreamRead = ADODB_Stream\GetVariantProperty("Read")
            
            ADODB_Recordset\SetProperty("Fields('Foto_Image')\Value="  + Str(*varStreamRead) + " As Variant")
            
            VariantClear_(*varStreamRead)
            
            ADODB_Recordset\Invoke("Update")
            ADODB_Recordset\Invoke("Close")
            
          Else
            Debug "!ADODB_Recordset.Open(): " + COMate_GetLastErrorDescription()
          EndIf
          
          ADODB_Recordset\Release()
          
        Else
          Debug "!ADODB_Recordset: " + COMate_GetLastErrorDescription()
        EndIf
        
        ADODB_Stream\Invoke("Close")
        ADODB_Stream\Release()
        
      Else
        Debug "!ADODB_Stream: " + COMate_GetLastErrorDescription()
      EndIf
      
      ADODB_Connection\Invoke("Close")
      
    Else
      Debug "!ADODB_Connection.Open(): " + COMate_GetLastErrorDescription()
    EndIf
    
    ADODB_Connection\Release()
    
  Else
    Debug "!ADODB_Connection: " + COMate_GetLastErrorDescription()
  EndIf
  
EndProcedure

Procedure ReadImageFromDatabase(ConnectionString.s, Foto_Nummer, Foto_Image.s)
  
  Protected ADODB_Connection.COMateObject  ; Connection-Objekt
  Protected ADODB_Recordset.COMateObject   ; Recordset-Object
  Protected ADODB_Stream.COMateObject      ; Stream-Object
  Protected *varStreamRead.VARIANT
  
  ADODB_Connection = COMate_CreateObject("ADODB.Connection")
  
  If ADODB_Connection 
    
    If ADODB_Connection\Invoke("Open('" + ConnectionString + "')") = #S_OK
      
      ADODB_Stream = COMate_CreateObject("ADODB.Stream")
      
      If ADODB_Stream
        
        ADODB_Stream\SetProperty("Type=" + Str(#adTypeBinary))
        ADODB_Stream\Invoke("Open")
        
        ADODB_Recordset = COMate_CreateObject("ADODB.Recordset")
        
        If ADODB_Recordset
          
          If ADODB_Recordset\Invoke("Open('SELECT Foto_Nummer, Foto_Image FROM gamepics Where Foto_Nummer=" + Str(Foto_Nummer) + "', " + Str(ADODB_Connection) + " As COMateObject, " + Str(#adOpenKeyset) + ", " + Str(#adLockOptimistic) + ")") = #S_OK
            
            *varStreamRead = ADODB_Recordset\GetVariantProperty("Fields('Foto_Image')\Value")
            
            ADODB_Stream\Invoke("Write(" + Str(*varStreamRead) + " As Variant)" )
            
            VariantClear_(*varStreamRead)
            
            ADODB_Stream\Invoke("SaveToFile('" + ReplaceString(Foto_Image, "'", "$0027") + "', " + Str(#adSaveCreateOverWrite) + ")")
            
            ADODB_Recordset\Invoke("Close")
            
          Else
            Debug "!ADODB_Recordset.Open(): " + COMate_GetLastErrorDescription()
          EndIf
          
          ADODB_Recordset\Release()
          
        Else
          Debug "!ADODB_Recordset: " + COMate_GetLastErrorDescription()
        EndIf
        
        ADODB_Stream\Invoke("Close")
        ADODB_Stream\Release()
        
      Else
        Debug "!ADODB_Stream: " + COMate_GetLastErrorDescription()
      EndIf
      
      ADODB_Connection\Invoke("Close")
      
    Else
      Debug "!ADODB_Connection.Open(): " + COMate_GetLastErrorDescription()
    EndIf
    
    ADODB_Connection\Release()
    
  Else
    Debug "!ADODB_Connection: " + COMate_GetLastErrorDescription()
  EndIf
  
EndProcedure

Define.s SqlServer, SqlServerDatabase, SqlServerUsername, SqlServerPassword
Define.s ConnectionString

SqlServer         = "mySqlServer"
SqlServerDatabase = "mySqlServerDatabase"
SqlServerUsername = "myUsername" ; SQL Server-Authentification
SqlServerPassword = "myPassword" ; SQL Server-Authentification
  
; Windows-Authentification:
ConnectionString = "Provider=SQLOLEDB.1;Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=" + SqlServerDatabase + ";Data Source=" + SqlServer
  
; SQL Server-Authentification:
; ConnectionString = "Provider=SQLOLEDB.1;Persist Security Info=True;Password=" + SqlServerPassword + ";User ID=" + SqlServerUsername + ";Initial Catalog=" + SqlServerDatabase + ";Data Source=" + SqlServer

WriteImageToDatabase (ConnectionString, 2, "C:\MyInImage.png")

ReadImageFromDatabase(ConnectionString, 2, "C:\MyOutImage.png")

Debug "Ready"
ich habe mich an Deine Tabellenstruktur gehalten, so dass Du lediglich nur noch
den COMate-Includepfad und die Zugangsdaten zum SQL Server anpassen musst.

Falls noch Klärungsbedarf ist, dann weißt Du ja, wo ich bin ;-)

Grüße ... Kiffi

// EDIT

29.01.2010: Speicherleck behoben
Zuletzt geändert von Kiffi am 29.01.2010 13:43, insgesamt 1-mal geändert.
a²+b²=mc²
Benutzeravatar
Lupo
Beiträge: 147
Registriert: 16.02.2005 15:15

Re: Wie bring ich Fotoimages in eine SQL Server 2005 Datenbank ?

Beitrag von Lupo »

Wahnsinn! Es funktioniert! Danke! :D :D
Kiffi ist Spitze :allright: :allright:
Dank auch an den comate Autor, ist ganz schön kompliziert.

Jetzt werde ich noch versuchen den code auch zu begreifen, abschreiben ist einfach aber zu wenig.

Wenn ich mehrere Fotos auf einmal einstellen möchte, dann kann man eine Schleife mit

Code: Alles auswählen

ADODB_Stream = COMate_CreateObject("ADODB.Stream")
machen, damit man die Connection nicht immer neu aufmachen muss?

Ist es sinnvoll, die Connection am Anfang des Programms zu öffnen und wenn man beendet zu schliessen? oder ist es besser nicht länger offen zu lassen und jedes mal zu schließen, könnte ja wer auch weggehen vom aktiven Programm und eine Stunde passiert nichts.

Dann will ich fragen, ob man die ADO Connection auch für die normalen PB Database Befehle nutzen kann, etwa dass man ein DNS=MYSUPERPICS in den Connectionstring einbaut und dann mit der DNS das Opendatabase() verwendet.

Wenn man das nicht kann, kann man dann beide connections (ADo unn PB) gleichzeitig öffnen oder passiert da was Böses? :|

Ich frage deshalb bevor ich da rumprobiere weil es ja eine fremde Datenbank ist und wenn der admin dort merkt, dass da gepfuscht wird, ist mir das nicht recht.

Nachdem ich schon viele DB Abfragen mit der Database() Lib geschrieben habe, möchte ich das nicht unbedingt mit Comate + ADO machen. Die echte Fotodatenbank ist natürlich komplizierter mit vielen Spalten als die Testfotodatenbank mit den 2 Spalten.

Danke Lupo
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Wie bring ich Fotoimages in eine SQL Server 2005 Datenbank ?

Beitrag von Kiffi »

Mein Code hat noch ein Speicherleck. Wenn man viele Bilder in die
Datenbank schaufelt, steigt der Speicherverbrauch ständig an.
(danke @Lupo für den Hinweis)

Anscheinend gibt COMate (oder PureBasic?) den Speicher bei Variants
nicht automatisch frei. Ich habe den Source mal ein wenig abgeändert
und siehe da: Das Speicherleck ist weck, äh, weg ;-)

Folgende Zeile:

Code: Alles auswählen

ADODB_Recordset\SetProperty("Fields('Foto_Image')\Value="  + Str(ADODB_Stream\GetVariantProperty("Read")) + " As Variant")
muss durch folgenden Schnippsel ersetzt werden:

Code: Alles auswählen

*varStreamRead = ADODB_Stream\GetVariantProperty("Read")
ADODB_Recordset\SetProperty("Fields('Foto_Image')\Value="  + Str(*varStreamRead) + " As Variant")
VariantClear_(*varStreamRead)
*varStreamRead wird wie folgt im Procedure-Kopf deklariert:

Code: Alles auswählen

[...]
Protected *varStreamRead.VARIANT
[...]
Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Lupo
Beiträge: 147
Registriert: 16.02.2005 15:15

Re: Wie bring ich Fotoimages in eine SQL Server 2005 Datenbank ?

Beitrag von Lupo »

Danke an Kiffi :allright: für das Beseitigen des Speicherlecks.

Werde mal rumprobieren wie das zustandekommt, weil im Comate wird ganz normal mit AllocateMemory der Speicher reserviert und man kann ihn später auch mit Freememory wieder freigeben aber er ist nicht wirklich freigegeben :wink:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Wie bring ich Fotoimages in eine SQL Server 2005 Datenbank ?

Beitrag von ts-soft »

Lupo hat geschrieben:Danke an Kiffi :allright: für das Beseitigen des Speicherlecks.

Werde mal rumprobieren wie das zustandekommt, weil im Comate wird ganz normal mit AllocateMemory der Speicher reserviert und man kann ihn später auch mit Freememory wieder freigeben aber er ist nicht wirklich freigegeben :wink:
siehe hier: http://www.purebasic.fr/german/viewtopi ... 01#p264701
Antworten