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
Hi,
sieh mal hier:
http://shop.minhorst.com/media/pdf/ASQL_LP_SQLServerUndBilder.pdf
sollte das wesentliche zu lesen sein.
Andreas
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 FunctionDie 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;
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.
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.
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.
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.
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.
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 :)