Direkter Zugriff auf BLOB-Felder

19. April 2013 09:21

Guten Morgen,

http://devch.wordpress.com/2013/01/17/accessing-compressed-blobs-from-outside-nav-nav2013/

Hat das schon mal jemand getestet? Klappt das auch mit früheren Versionen?

Volker

Re: Direkter Zugriff auf BLOB-Felder

19. April 2013 09:33

In the new Version, the BLOB compression is no longer a proprietary format, ...


I guess not.

Re: Direkter Zugriff auf BLOB-Felder

19. April 2013 09:38

So lese ich das auch, aber was ist bei einem Upgrade von 2009 nach 2013? Wird da jedes Blobfeld in das neue Format konvertiert? Kann ja mitunter ewig dauern. Das kann ich mir nicht vorstellen.


Volker

Re: Direkter Zugriff auf BLOB-Felder

2. Juni 2013 07:17

Hallo an alle,

ich habe mit das mal angeschaut und habe da mal meine eigene kleine Funktion in c# gebastelt.
8-) :-P
Damit ist es möglich, auf für Add-Ins (nicht nur für Client-Control-Add-Ins), sich beliebig Notizen zu holen.
- z.B. eigene DotNet-DLL

Code:
internal string ReadNoteDate(int Sqlkey)
        {
            try
            {
                string retStr = null;
               
                #region SQL-Query
                SqlConnection myCon = new SqlConnection();
                myCon.ConnectionString = BuildConStr(MyServerInstance, MyDatabase);
                SqlCommand myCommand = new SqlCommand("Select Note FROM [Record Link] WHERE [Link ID] = @LinkId", myCon);
                SqlParameter myParameter = new SqlParameter("@LinkId", System.Data.SqlDbType.Int);
                myParameter.Value = Sqlkey;
                myCommand.Parameters.Add(myParameter);
                myCon.Open();
                #endregion

                SqlDataReader myReader = myCommand.ExecuteReader();
               
                if (myReader.HasRows == true)
                {
                    if (myReader.Read())
                    {
                        MemoryStream outsqlstream = new MemoryStream();
                        // Read with this startindex because NAV and also NAV 2013 stores the length of the BLOB in the fist four bytes
                        // This is the rease why i read the datas not with SQLBytes
                       [b] long startIndex = 4;[/b]                        const int ChunkSize = 256;
                        while (true)
                        {
                            byte[] buffer = new byte[ChunkSize];
                            long retrievedBytes = myReader.GetBytes(0, startIndex, buffer, 0, ChunkSize);
                            outsqlstream.Write(buffer, 0, (int)retrievedBytes);
                            startIndex += retrievedBytes;
                            if (retrievedBytes != ChunkSize)
                                break;
                        }

                        MemoryStream outstream = new MemoryStream();
                        outsqlstream.Position = 0;
                        DeflateStream decompressedstream = new DeflateStream(outsqlstream, CompressionMode.Decompress);
                        decompressedstream.CopyTo(outstream);
                        outstream.Seek(0, SeekOrigin.Begin);
                        Encoding MyEnc = Encoding.UTF8;
                        BinaryReader BinReader = new BinaryReader(outstream, MyEnc);
                        retStr = BinReader.ReadString();
                       
                        // Close streams don't wait for GAC
                        outsqlstream.Close();
                        outstream.Close();
                        decompressedstream.Close();
                     }
                }
                else
                {
                  // record not found
                    return rmML.GetString("Error4");
                }
                myCon.Close();
                return retStr;
            }
            catch (Exception ex)
            {
                // error while read
                return(ex.Message);
            }
        }


Das ganze habe ich mit NAV 2013 aktueller Build aus dem RU2 getestet und es tut auch mit Umlauten.
Ich kann mit nicht vorstellen, das es unter 2009 R2 funktioniert, :-( da hier meines Wissens die Kommpression der BLOB - Daten mit einem uralten Algorithmus erfolgt, den keiner mehr kennt.
Das Wichtigste an obiger Lösung ist das Überlesen der ersten vier Bytes des BLOB-Feldes (fett markiert), da NAV diese Bytes für interne Zwecke (länge des BLOB ????) verwendet. Auf diesem Umstand wurde auch in den aktuellsten Beiträgen nicht eingegangen. Das führte dann eben auch zu etwas ungewöhnlichen Ausgaben von Feldinhalten, wenn man den Inhalt vorher dekomprimiert hat.

Wenn wer noch was dazu etwas beitragen kann, dann lasst es mich (uns) wissen.

MFG Micha