Access-o-Mania

Datenbanken (Deutsch/German) => MS SQL-Server => Thema gestartet von: datekk am Juni 01, 2016, 22:03:45

Titel: Bitte um Hilfe bei FileTable
Beitrag von: datekk am Juni 01, 2016, 22:03:45
Hi Leute,

kennt sich jemand mit FileTables auf nem SQL Server aus? Meine Access Backend ist nun ein SQL Express 2014 Server. Die Verbindung dazu wird via ODCB ÜBER DAS INTERNET aufgebaut und die Tabellen sind verknüpft. Alles läuft dufte soweit... bis auf das Speichern von z.B. Bildern im FileTable. Immer wenn ich der gespeicherten Prozedur auf dem SQL Server einen Pfad übergebe findet der die Datei nicht, da er in seinem eigenen Dateisystem danach sucht - die Datei liegt aber auf meinem Rechner.

Leider habe ich keine Ahnung, wie ich eine Datei an den FileTable gebe, welche auf einem Server liegt, der nur über das Netz zu erreichen ist.

Ich hoffe, jemand kann mir helfen.

LG
datekk
Titel: Re: Bitte um Hilfe bei FileTable
Beitrag von: Hondo am Juni 01, 2016, 23:02:54
Hi,
sieh mal hier:
http://shop.minhorst.com/media/pdf/ASQL_LP_SQLServerUndBilder.pdf

sollte das wesentliche zu lesen sein.
Andreas
Titel: Re: Bitte um Hilfe bei FileTable
Beitrag von: datekk am Juni 01, 2016, 23:19:28
Danke Hondo, aber ich hab das Buch hier vor mir liegen. Der Autor behandelt die Situation, das SQL Server und Access Datenbank auf DEM SELBEN Rechner liegen. Genau hier ist das Problem:

ZitatImmer wenn ich der gespeicherten Prozedur auf dem SQL Server einen Pfad übergebe findet der die Datei nicht, da er in seinem eigenen Dateisystem danach sucht - die Datei liegt aber auf meinem Rechner.

Hier ist die Function, die ärger macht:

Public Function SPAktionsabfrageMitErgebnis(strStoredProcedure As String, _
        strVerbindungszeichenfolge As String, _
        bolRueckgabeInSPImplementiert As Boolean, _
        strRueckgabeausdruck As String, _
        ParamArray varParameter() As Variant) As Variant
    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    Dim rst As DAO.Recordset
    Dim strParameter As String
    Set db = CurrentDb
    Set qdf = db.CreateQueryDef("")
    strParameter = Parameterliste(varParameter)
    With qdf
        .Connect = strVerbindungszeichenfolge
        .ReturnsRecords = True
        .SQL = "EXEC " & strStoredProcedure & " " & strParameter
        If Not bolRueckgabeInSPImplementiert Then
            If Len(strRueckgabeausdruck) = 0 Then
                .SQL = .SQL & vbCrLf & "SELECT @@ROWCOUNT AS RecordsAffected;"
            Else
                .SQL = .SQL & vbCrLf & strRueckgabeausdruck
            End If
        End If
        Set rst = .OpenRecordset
    End With
    SPAktionsabfrageMitErgebnis = Nz(rst.Fields(0))
    Set db = Nothing
End Function


Die Variable strParameter enthält 1. den Dateinamen unter der die Datei auf dem Server gespeichert werden soll und 2. den Pfad zur Datei, welche in die Filetable aufgenommen werden soll. Dieser Pfad wird aber vom Client Rechner übergeben und der SQL Server sucht auf seiner eigenen Platte nach der Datei. An der Stelle Set rst = .OpenRecordset bricht die Ausführung ab, da die Datei nicht gefunden werden kann, was auch logisch ist.

Die gespeicherte Prozedur auf dem SQL Server sieht so aus:

ALTER proc [dbo].[spBildHinzufuegen]
@Bildname nvarchar(255),
@BildPfadUndName nvarchar(255)
As
set NoCount On;
Declare @SQL nvarchar(max);
SET @SQL = 'INSERT INTO dbo.tblArtikelbilder (name,file_stream)
SELECT ''' + @Bildname + ''', *
From OPENROWSET(Bulk ''' + @BildPfadUndName + ''', SINGLE_BLOB) AS FileData'
EXEC sp_executesql @SQL
SELECT FILETABLEROOTPATH() + file_stream.GetFileNamespacePath() as Dateiname
From dbo.tblArtikelbilder WHERE name = @Bildname;
Titel: Re: Bitte um Hilfe bei FileTable
Beitrag von: DF6GL am Juni 02, 2016, 08:11:01
Hallo,

naja, wenn der Filename als solches nicht in dieser Konstellation gefunden werden kann, dann muss die Datei eben auf einem "öffentlichen" Netz-Speicherplatz abgelegt werden, was vermutlich aber nicht so gewünscht ist oder praktikabel ist.

Ansonsten ist  auch das Speichern/Lesen  der Bild-Daten (Datei-Inhalt, nicht Dateiname)  in/aus einem Blob-Feld anzudenken.  Das erhöht aber auf jeden Fall den Netzwerk-Traffic.



Titel: Re: Bitte um Hilfe bei FileTable
Beitrag von: datekk am Juni 02, 2016, 08:55:24
Hallo Franz,

danke für Deine Antwort. Ein öffentlicher Speicherplatz war auch meine erste Überlegung, es scheitert nur einfach daran, dass es scheinbar keinen öffentlichen Speicherplatz gibt, mit dem ich Access von verschiedenen Rechnern aus verbinden kann.

Die beste Lösung für meine Datenbank stellt wirklich das Lesen und Speichern in die Datenbank direkt dar. Es handelt sich hierbei nicht um große Dateimengen. Es geht um Signaturen, kleine Icons und Briefbögen.

In meiner Filestreamtabelle habe ich z.B. das Feld "file_stream" als varbinary(max). Ich nehme an, dies ist das Blob Feld. Wie kann ich denn den Dateiinhalt an ein solches Feld übergeben nachdem ich den Pfad mittels Filedialog zur Datei ermittelt habe. Hier müsste sicher der Dateiinhalt an eine Variable übergeben werden und diese übergebe ich dann mit dem zu speichernden Dateinamen der Prozedur auf dem SQL Server, welche diese in das Feld schreibt.

Gefunden habe ich im Netz z.B. dies: http://www.access-im-unternehmen.de/183.0.html (http://www.access-im-unternehmen.de/183.0.html)

Nur erscheint es mir recht aufwendig, die Datei immer erst in ein Temp Verzeichnis des Clients zu laden um diese dann von dort aus anzeigen zu können.

Besteht eigentlich die Möglichkeit, das Filestreamverzeichnis des Servers über das Internet zu erreichen um somit den Pfad zur Bilddatei im Filestream direkt nutzen zu können? Meine Versuche mit \\benutzer:passwort@rechner\freigabe scheiterten jedoch obwohl ich die Ports 139 und 445 im Router und in der Firewall des SQL Servers freigegeben habe. Der Filestream ist nur im LAN erreichbar. Könnte man dies ändern, würde sicher auch das Zwischenspeichern der Datei auf dem ClientPC wegfallen.

Oder wäre es möglich, in einer "normalen SQL Tabelle" ein varbinary(max) Feld anzulegen und den Dateiinhalt dort zu lagern und ein Bild-Steuerelement direkt daraus zu bedienen? Es müssten dann aber Dateien wie gif und jpg funktionieren und nicht nur Bitmap.
Titel: Re: Bitte um Hilfe bei FileTable
Beitrag von: DF6GL am Juni 02, 2016, 09:31:00
Hallo,



ZitatBesteht eigentlich die Möglichkeit, das Filestreamverzeichnis des Servers über das Internet zu erreichen

Das bezweifle ich und überhaupt würde das den Sicherheitsüberlegungen bei einem SQL-Server völlig widersprechen...

Zitatund den Dateiinhalt dort zu lagern und ein Bild-Steuerelement direkt daraus zu bedienen

Inwieweit ein gebundenes OLE-Steuerelement an einem BLOP-Feld im SQL-Server funktioniert, kann ich jetzt nicht sagen. Halt einfach ausprobieren.
Titel: Re: Bitte um Hilfe bei FileTable
Beitrag von: datekk am Juni 02, 2016, 09:53:17
Ok, habe hier konkrete Ansätze gefunden: http://www.access-basics.de/index.php/Bilder_in_Access,_Teil_II:_Bilder_in_OLE-Feldern.html (http://www.access-basics.de/index.php/Bilder_in_Access,_Teil_II:_Bilder_in_OLE-Feldern.html)

Herr Minhorst hat wieder Geld verdient, aber ok.  ::)

Ich werde berichten.

Titel: Re: Bitte um Hilfe bei FileTable
Beitrag von: PhilS am Juni 02, 2016, 12:34:24
Zitat von: datekk am Juni 02, 2016, 08:55:24Oder wäre es möglich, in einer "normalen SQL Tabelle" ein varbinary(max) Feld anzulegen und den Dateiinhalt dort zu lagern und ein Bild-Steuerelement direkt daraus zu bedienen? Es müssten dann aber Dateien wie gif und jpg funktionieren und nicht nur Bitmap.
Jein. Kommt auf deine Definition von "direkt" an.  Wenn ich mich richtig erinnere, ist es nicht möglich das Feld an ein Bildsteuerelement zu binden. Du kannst aber mit wenigen Zeilen VBA die Binärdaten auslesen und dann an das Steuerelement als Inhalt zuweisen. In Einzelformularen funktioniert das sehr gut und einfach, in Endlosformularen allerdings nicht.
Titel: Re: Bitte um Hilfe bei FileTable
Beitrag von: datekk am Juni 02, 2016, 13:21:59
Hallo PhilS,

danke, ich bin auch auf genau diesen Ansatz gestoßen und versuche die nächsten Tage dies auf die Beine zu stellen. In Endlosformularen brauche ich es auch nicht, aber in Berichten. Hier gibt es aber im Detailsbereich ein Ereignis, mit dem ich via VBA für jeden Datensatz Zugriff habe.

We will see was bei rauskommt :)