none
VARBINARY(MAX) fuer files [SQL SERVER 2005 .NET 4 VB WindowsForms ] RRS feed

  • Frage

  • Hallo SQLServer Experten,

    ich moechte Files die irgendwo auf der Platte stehen auf dem SQLServer speichern. Dazu habe ich eine Tabelle erstellt, die unterer anderm, auch eine Spalte des Types VARBINARY(MAX) enthaelt. Dort sollen z.B Zip-Files oder auch simple Textfiles oder andere Formate untergerbracht werden.
    Wichtig ist, das immer nur die Daten zwischen SERVER und File Sytem ausgetauscht werden. Es ist nicht daran gedacht, die Daten in der Applikation [VB Windows Forms] zu interpretieren.

    Kann es unter diesen Bedingungen noch irgenwelche Probleme geben ?

    Wie kommen die Daten auf den Server ?
    Muss der Server die files "adderessiren koennen" oder wie jann ich das mit WindowsForms loesen ?

    Fuer Tips , Beispielcode SQL , VB vielen Dank

    Rolf

    Freitag, 29. Oktober 2010 12:15

Antworten

Alle Antworten

  • Hallo Rolf,

    es gibt viele Möglichkeiten, um varbinary Daten zu Importieren/Exportieren. Hier findest Du Info über die SQL Server-Mitteln:

    OPENROWSET (Transact-SQL)

    • create table test.dbo.files
      (
       [file_id] int identity(1,1) not null,
       [file_name] nvarchar(60) not null,
       [document] varbinary(max)
      )
      go
      
      insert into test.dbo.files([file_name],document)
      select
       'test.txt' as [file_name], 
       * from openrowset(bulk N'c:\test.txt', single_blob) as document
      go
      

    bcp (Hilfsprogramm)

    • bcp "select document from test.dbo.files where file_id = 2" queryout C:\test1.txt -T

    SQL Server Integration Services

     

    Gruß Yury
    Samstag, 30. Oktober 2010 00:49
  • Wichtig ist, das immer nur die Daten zwischen SERVER und File Sytem ausgetauscht werden. Es ist nicht daran gedacht, die Daten in der Applikation [VB Windows Forms] zu interpretieren.

    Kann es unter diesen Bedingungen noch irgenwelche Probleme geben ?


    Hallo Rolf,

    das setzt voraus, dass der Account unter dem der SQL Server Dienst läuft, Zugriff auf die Dateien hat. In der Regel lässt man den Dienst unter "LocalSystem" laufen und der Account hat normalerweise nur Zugriff auf lokale Resourcen, nicht auf Netzlaufwerke.

    Man kann den Dienst auch unter einem normalen Domain Account laufen lassen, der die entsprechende Rechte hat und die Rechte auf den Netzwerk Shares abändern, so das der SQL Server trotzdem zugreifen kann. Hier muss man halt sich vorher überlegen, was aus Sicherheits-technischen Gesichtspunkten die beste Lösung ist.

     


    Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de
    Samstag, 30. Oktober 2010 04:48
  • Hallo Yuri (und Olaf )

    danke fuer die Antwort.

    Ich habe da noch ein prinzipielles Verstaendnissproblem:

    So wie das aussieht hat der SQL server immer fuer den Filezugriff zu sorgen.
    ich hatte die Hoffnuing das ich die Daten vom meinem client aus als "SQL COMMAND" uebergeben kann.

    Ideal ware eine SP die als paramenter die record_id und die wirklichen Daten und nicht einen file pointer bekommt.
    Geht das irgendwie ?

    Rolf

    Samstag, 30. Oktober 2010 10:46
  • Hallo Rolf,

    Database Objects

    create table dbo.files
    (
    	[file_id] int identity(1,1) not null,
    	[file_name] nvarchar(60) not null,
    	[document] varbinary(max)
    )
    go
    
    create proc store_file
    	@file_name nvarchar(60),
    	@document as varbinary(max)
    as
    begin
    	insert into dbo.files([file_name],document)
    	values(@file_name, @document)
    end
    go
    

    C# ConsoleApplication speichert eine Datei mit dem Pfad c:\test.txt in die Datenbank Test

    using System;
    using System.IO;
    using System.Data.SqlClient;
    
    namespace ConsoleApplication
    {
      class Test
      {
        public static void Main()
        {
          string pathSource = @"c:\test.txt";
          try
          {
            using (FileStream fsSource = new FileStream(pathSource, FileMode.Open, FileAccess.Read))
            {
              byte[] bytes = new byte[fsSource.Length];
              int numBytesToRead = (int)fsSource.Length;
              int numBytesRead = 0;
              while (numBytesToRead > 0)
              {
                int n = fsSource.Read(bytes, numBytesRead, numBytesToRead);
    
                if (n == 0)
                  break;
                numBytesRead += n;
                numBytesToRead -= n;
              }
    
              SqlConnection sqlConnection = 
                  new SqlConnection("Integrated Security=true;server=(local);initial catalog=test");
              try
              {
                SqlCommand sqlCommand = new SqlCommand();
                sqlCommand.Connection = sqlConnection;
                sqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
                sqlCommand.CommandText = "[dbo].[store_file]";
                sqlCommand.Parameters.Add(new SqlParameter("file_name", pathSource));
                sqlCommand.Parameters.Add(new SqlParameter("document", bytes));
    
                sqlConnection.Open();
                sqlCommand.ExecuteNonQuery();
                Console.WriteLine("file saved");
              }
              catch (Exception e)
              {
                Console.WriteLine(e.Message);
              }
              finally
              {
                if (sqlConnection.State==System.Data.ConnectionState.Open)
                {
                  sqlConnection.Close();
                }
              }
    
            }
          }
          catch (FileNotFoundException ioEx)
          {
            Console.WriteLine(ioEx.Message);
          }
          Console.ReadKey();
        }
      }
    }
    

    Gruß Yury
    Samstag, 30. Oktober 2010 16:37
  • Hallo Rolf,

    suchst Du nach so etwas hier: Bilder in einer MS SQL Tabelle ablegen?
    (wobei "Bilder" ein beliebiges Dokument sein kann)

    Was ursprünglich von mir für VB.NET erstellt wurde
    und in dem Beitrag auf C# portiert und erweitert -
    rückwärts dann bei Bedarf ;-)

    Gruß Elmar

    Samstag, 30. Oktober 2010 17:32
    Beantworter