Blog Home  Home Feed your aggregator (RSS 2.0)  
Freakfabrik Softwareschmiede - Das Blog
newtelligence powered
 
 Monday, January 15, 2007
Fehlercode:
    800a0e78

Fehlermeldung:

    The operation requested by the application is not allowed if the object is closed.
    ADODB.Recordset Fehler "800a0e78' - Der Vorgang ist für ein geschlossenes Objekt nicht zugelassen.


Ursache:

sql = "Insert into #Tabelle [..]" & vbcrlf & _
       "Select * from #Tabelle"
db.execute(sql)


Das Problem ist das hier zwei Statements nacheinandere abgearbeitet werden womit ADODB leider nicht so klar kommt wie man es erwarten würde. Genauer betrachtet macht ADODB genau das was es soll. Es liefert 2 Recordsets zurück. Das erste behandelt den das erste Statement was nach seiner Ausfühung ohne Rückgabe gleich wieder geschlossen wurde.

Lösung:

    Ansatz 1: Man führt einfach beide Anweisungen sperat aus.
    Ansatz 2: Ein "SET NOCOUNT ON" als erste Anweisung behebt ebenfalls das Problem.
      

Monday, January 15, 2007 4:18:54 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [1]    | 
 Friday, January 12, 2007
Ein Freund von mir bat mich für ihn eine Klasse zu schrieben mit der man MD5-Hash von Files erzeugen kann. Da er noch nicht viel Erfahrung mit .Net hat willigte ich ein. Dabei stellte ich jedoch fest das es viele verschiedene Ansätze gibt die jeweils unterschiedliche Resultate erzeugten. Also erzeugte ich mit dem Tool MD5sum.exe ein paar Referenzwerte um meine Ergebnisse zu vergleichen.

    1 Imports System.Security.Cryptography

    2 Imports System.Text

    3 Imports System.IO

    4 

    5 Public Class MD5FileHash

    6     Public Function getMD5HashForFile(ByVal strFileName As String) As String

    7         If (New FileInfo(strFileName).Exists) Then

    8             Dim objSB As New StringBuilder

    9             Dim objMD5 As New MD5CryptoServiceProvider

   10             Dim objFS As New FileStream(strFileName, FileMode.Open)

   11             Dim bHash() As Byte = objMD5.ComputeHash(objFS)

   12             objFS.Close()

   13             For Each bHex As Byte In bHash

   14                 objSB.Append(bHex.ToString("x2"))

   15             Next

   16             Return objSB.ToString

   17         Else

   18             Throw New FileNotFoundException("File " & strFileName & " not Found.")

   19             Return Nothing

   20         End If

   21     End Function

   22 End Class



Wichtig ist das die Referenz auf System.Security bestehen muss. Diese Funktion erzeugt MD5-Hash-Werte von Dateien die unter anderem zu den Hash-Werten von MD5sum.exe, digestIT und der MD Hash Tool extension for Firefox kompatibel sind.

Friday, January 12, 2007 11:16:05 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 
 Thursday, January 11, 2007
Und zugleich erfolgt der zweite Blogeintrag für Heute. Diesmal befasse ich mich mit dem Problem die Version des Acrobat's respektive Acrobat Reader's im Internetexplorer auszulesen.

Das kniflige dabei ist das ich nicht VBScript zurückgreifen möchte. Das hat eine einfachen Grund. Die viele Benutzer haben VBScript deaktiviert oder auf "Eingabeaufforderung" gestellt was zu einem nervigen PopUp führen würde.

    1 function getAcrobatVersionsNr(style){ //Parameters Accept: short (Return X.X) | long (Return X.X.X) || Returns is none Acrobat detectet NULL

    2     document.write('<object id="pdfObj" classid="clsid:CA8A9780-280D-11CF-A24D-444553540000" width="0" height="0" style="display:none"></object>');

    3     try{

    4         AcrobatVersion = pdfObj.GetVersions();

    5         if(AcrobatVersion == '')

    6             return null;

    7         else{

    8             var indice = AcrobatVersion.indexOf("AcroForm");

    9             if (indice>-1) {

   10                 indice = indice + 9;

   11                 var AcrobatVersionNrLang = AcrobatVersion.substring(indice, indice + 5)

   12                 indice=AcrobatVersionNrLang.lastIndexOf(".")

   13                 AcrobatVersionNrKurz = AcrobatVersionNrLang.substring(0,indice);

   14                 if (style=='short')

   15                     return AcrobatVersionNrKurz;

   16                 else if (style=='long')

   17                     return AcrobatVersionNrLang;

   18             }

   19             else

   20                 return null

   21 

   22         }

   23     }

   24     catch(ex){return null}

   25 }



Die Funktion getAcrobatVersionsNr erstellt ein neues Objekt der angegebenen classid welches das AcrobatBowserHelper-Objekt representatiert. Anschließend wird geprüft ob sich dieses Objekt instanzieren ließe und wenn ja wird die Funktion GetVersions aufgerufen welche einen String mit allen installierten AcrobatPlugins und deren Versionen auflistet. Das wichtigste Plugin in diesem Zusammenhang ist AcroForm. Nun wird die Versionsinformation dieses Plugins rausgeparst.

Die Funktion verfügt über einen Parameter der angibt in welchem Format die Rückgabe erfolgen soll. Zur Auswahl stehen hier "short" und "long". Weitere Informationen entnehmen Sie bitte dem Kommentar.

Sollte keine Acrobatversion installiert sein wird NULL zurückgegeben.

Thursday, January 11, 2007 4:56:19 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 
Nach einer kurzen Ruhepause möchte ich nun wieder mit meiner Arbeit beginnen. Und gleich bin ich auf das erste Problem gestoßen.

Im Namespace System.Web gibt es eine Klasse die sich HttpUtility nennt und die unter anderem die Funktion Urlencode und Urldecode implementiert. Leider hatte ich feststellen müssen das diese Klasse nicht das macht was ich wollte. Mittels des WebClients aus dem System.Net Namespace wollte ich einen Request absätzen der jedoch als Parameter auch umlaute enthielt. Diese wurde jedoch nicht encodiert und auch der WebClient encodiert sie nicht automatisch.

Aus diesem Grund habe ich mich drangemacht selber eine entsprechende Implementierung zu schreiben und das Resultat möchte ich euch hier zur Verfügung stellen.

    1     Public Function UrlEncode(ByVal strValue As String) As String

    2         Dim strTempreturn As String = ""

    3         For Each strChar As Char In strValue

    4             If InStr(1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", strChar) = 0 Then

    5                 strTempreturn += "%" & Hex(Asc(strChar))

    6             Else : strTempreturn += strChar

    7             End If

    8         Next

    9         Return strTempreturn

   10     End Function

   11 

   12     Public Function UrlDecode(ByVal strValue As String) As String

   13         Dim strTempreturn As String = ""

   14         Dim arrTempString() As String = strValue.Split("%")

   15         For Each strEntry As String In arrTempString

   16             If strEntry.Length >= 2 Then

   17                 If IsHex(strEntry.Substring(0, 2)) Then

   18                     strTempreturn += Chr("&H" & strEntry.Substring(0, 2))

   19                     strTempreturn += strEntry.Substring(2)

   20                 Else : strTempreturn += "%" & strEntry

   21                 End If

   22             Else : strTempreturn += strEntry

   23             End If

   24         Next

   25         Return strTempreturn

   26     End Function

   27 

   28     Public Function IsHex(ByVal strValue As String) As Boolean

   29         Dim bolTempreturn As Boolean = True

   30         If strValue.Length = 1 Or strValue.Length = 2 Then

   31             For Each strChar As Char In strValue

   32                 If InStr(1, "0123456789ABCDEF", strChar) = 0 Then

   33                     bolTempreturn = False

   34                 End If

   35             Next

   36         Else : bolTempreturn = False

   37         End If

   38         Return bolTempreturn

   39     End Function



Beide Funktionen erwartet einen String als Parameter und liefern ebenfalls einen String zurück.

Kurz zu den Funktionsweisen:

UrlEncode:

Diese Funktion prüft ob die im ubergebenen String enthaltenen Zeichen in der Zeichsatz (0-9a-zA-Z) passen (wobei ä,ü,ö,.. ignoriert werden). Sollte dem nicht so sein, wird der Hex-Wert des ASCII-Code dieses Zeichens ermittelt.

UrlDecode:

Diese Funktion teilt den übergebenen String anhand des %-Zeichens und prüft ob anschließend die nächsten zwei Zeichen einen Hex-Wert darstellen. Wenn ja wird dieser wieder in ein Char convertiert.

IsHex:

Diese Funktion überprüft lediglich ob die übergebene Zeichenfolge aus einem bzw. zwei Zeichen besteht und im Zeichsatz für Hex-Werte enthalten ist.


Thursday, January 11, 2007 1:34:37 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 
 Tuesday, November 14, 2006
Die Fehlermeldung "Response Buffer Limit Exceeded" wird vom IIS geworfen sobald der Puffer einer Webseite eine Größe von 4 MB - 4194304 Byte - überschreitet. Dies trifft auch auf alle eingebetteten Objecte wie Bilder, PDFs und äühnliches zu die direkt ins ASP eingebunden sind.

Für dieses Problem gibt es verschiedene Lösungen.

Lösung 1 - Verwendung von Response.Flush:

Bei einer reinen HTML-Generrierung ist es möglich die Eigenschaft Response.Buffer zu setzten. Diese bewirkt das erstmal garnix besonderes. Erst im Zusammenhang mit mit Response.Flush() wird es interessant.

Sobald Response.Buffer auf True gesetzt wurde wird der generierte Seiteninhalt bis zum nächsten Auftreten von Response.Flush() oder dem Ende der Seite gechacht.

Hier ein kleines Beispiel

Response.Buffer = True
For i=0 to Ubound(arr)
   set RS = db.execute("Select from table where y=" & arr(i))
   Do While not rs.eof and rs.recordcount>1
     .....
   Loop
   Response.Flush()
Next
 

Lösung 2 - Anhebung des ASPBufferLimits:


Die zweite Lösung ist dann zu bevorzugen wenn es sich nicht um eine HTML-Generierung handelt. Als Beispiel kann ich hier zum Beispiel aufführen das eine PDF geladen werden soll die größer als 4MB ist - diesen Fall hatte ich heut selber gehabt.

Im AdminScripts-Verzeichnis des IIS (Inetpubs) findet sich das Script adsutil.vbs welches man wie folgt aufrufen muss.

cscript.exe adsutil.vbs SET w3svc/aspbufferinglimit LimitSize

LimitSize stellt die Puffer-Limit-Größe in Byte dar. Beispielsweise wird mit der Nummer 67108864 die Puffer-Limit-Größe zu 64 MB festgelegt.

Nach einem Neustart der IIS-Webinstanz wird die Einstellung übernommen und das Problem sollte nicht mehr auftreten.

Floyd
Tuesday, November 14, 2006 9:52:05 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [1]    |   | 
 Wednesday, November 08, 2006

Häufig stößt man in diversen Foren auf die Frage wie man in ASP NULL-Werte in eine Datenbank binden kann. Leider liefert ASP und ADODB keine Möglichkeit von Haus aus mit dies zu machen. Hierzu muss man sich einem kleinen Trick behelfen.

    1 dbNull = db.execute("select null").fields(0)


Natürlich kann man auch den weg gehen das man "NULL" direkt ins Statment schreib, doch dieser Weg ist weder besonders schön noch besonders empfehlenswert da dies zumeist doppelte Code-Pflege mit sich bringt.

Floyd

Wednesday, November 08, 2006 6:33:48 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [2]    | 

Im Artikel SQL-Injektion oder Wie binde ich richtig für Anfänger hatte ich vor einiger Zeit mal eine Funktionsblock gepostet um NULL in eine Datenbank zu binden. Da ich die Funktion jetzt mal wieder brauchte wollt ich sie natürlich gleich verbessern. Die neue Version ist um einiges schlanker und hat auch keinen begrenzten Typenumfang mehr.

   1     Function ReturnDBNull(ByVal value As Object) As Object

   2         If IsNothing(value) Or value = vbEmpty Or value = vbNull Then

   3             Return DBNull.Value

   4         Else

   5             Return value

   6         End If

   7     End Function


Floyd

Wednesday, November 08, 2006 6:26:41 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 
 Tuesday, November 07, 2006

Über dieses Blog

Diese Blog habe ich im April 2006 aus ein wenig Langeweile und auf der Suche nach etwas neuem auf die Beine gestellt mit dem Ziel es als eine Art privates Quellcodearchiv zu verwenden. Der Schwerpunkt dieses Blogs liegt dabei auf .NET-Technologie von Microsoft wobei ich mich nicht auf diese beschränke. Vorallem die Sprachen und Technologien die ich beruflich und privat einsetze - wie zum Beispiel Active Server Pages ASP, MSSQL (T-SQL) - möchte in in diesem Blog ebenfalls behandeln.
Hin und wieder kommt auch mal ein privater Post hinzu.

Über mich

Zu mir gibt es eigendlich nicht viel zu sagen. Ich wurde im August 1984 in Leipzig geboren und lebe seither in einem kleinen Dorf etwa 25km von Leipzig entfernt. Im Dezember 1996 bekamm ich meinen ersten eigenen Computer den ich mir durch viel Hausarbeit schwer erarbeiten musste. ^^ Internet war damals noch nicht und so musste ich mich mit einigen wenigen Zeitschriften und den WSH- und VBS-Scripten begügen. So begann ich meine ersten Begegnungen mit der Programmierei eher mit einigen spielereien an HTML, VBS und QBasic.Irgendwann viel mir dann in der Bücherrei ein Buch über Visual Basic in die Hand. Nachdem ich dieses Buch innerhalb von 2 Wochen begierig verschlugen hatte war wieder einmal Hausarbeit fällig :D denn das Visual Studio 6 musste her. Als Schüler-Version war diese auch relativ erschwinglich. Somit begann ich meine ersten Progrämmchen zu schreiben. Wärend die anderen in meiner Klasse noch überlegten was Sie werden wollten stand es für mich schon relativ zeitig Fest: Programmierer. Also beworb ich mich als Fachinformatiker für Anwendungsentwicklung und fand eine Ausbildung bei der Stadt Leipzig. Nachdem ich diese erfolgreich abschließen konnte musste ich eine weile Warten bis ich dann endlich eine Firma fand die mich einstellen wollte. Doch diese Zeit hab ich intensiv genutzt. .Net war grade frisch rausgekommen und wollte erobert werden. Zwischenzeitlich verdiente ich mich hin und wieder durch kleiner Projekte ein paar Euro dazu. Das größte war ein Verschlüsselungssystem für PDF-Dokumente für eine Schweitzer Bank. Damals gab es noch eine sehr aktive Community im programmierer-borad.de und Zusammen mit ein paar anderen Mitgliedern gründete ich damals das Projekt "Programmers-United" und leitetet dieses Projekt über ein paar Jahre lang bis es Aufgrund von Teilnahmemangel (begündet durch Abitur, Bund, etc. der aktivste Mitglieder) versiegte. Eine neue Aufgabe in der Community musste her. Ich stieß auf it-acamdey und bewarb mich als Mitglied der Artikeladministration. Mitlerweile bin ich Nun dort zum Bereichsleiter aufgestiegen.

Erfahungungen

  • VB.Net, ASP.Net (seit Version 1.0), Visual Basic 6, ASP, VBS, JavaScript, CSS, HTML, XML, SQL (T-SQL) und Grundlagen in: Java, C, C++, PHP, C#
  • MSSQL-Server (2000 und 2005), Firebird, Access, SQLite, MySQL
  • Windows 95 bis Vista, Windows 2000 Server bis 2003 und Grundlagen in: Linux (seit Suse Linux 7.0), Apple Mac OS X
  • Visual Studio .Net 2003 bis 2005, #Develop, CVS, Subversion
  • Microsoft Office, OpenOffice, Lotus Notes
  • ...

Ich denke das sollte es erstmal übermich gewesen sein. Wer noch Fragen hat kann sich gerne bei mir per eMail melden.

Tuesday, November 07, 2006 4:12:44 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 

Heute bin ich wiedermal in einem Forum auf die Frage gestoßen wie den Inhalt einer Variable in die Zwischenablage kopieren, jedoch soll der Inhalt der Zwischenablage auch nach Beendigung des Programms erhalten bleiben und somit anderen Programmen zur Verfügung stehen.

Die Lösung ist dabei Recht einfach. Die Funktion SetDataObject des Clipboard kopiert bekanntlicherweise den Inhalt einer Variable in die Zwischenablage. Einen zweite Parameter kann man jedoch optional noch angeben. Setzt man diesen auf "true" so sorgt er dafür, dass der Inhalt nicht nach Beendigung des Programms wieder gelöscht wird. Dies wird dann als "persistenz des Clipboard-Inhaltes" bezeichnet.

Dim strDaten As String = "TestString"

Clipboard.SetDataObject(strDaten, True)


Floyd

Tuesday, November 07, 2006 12:08:54 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [1]    | 
 Friday, October 06, 2006

Hab soeben auf DasBlog 1.9.6264.0 upgedatet. Hab die Grundkonfiguration erstmal wieder hergestellt. Morgen schau ich mir dann mal die Details an.

 

Gruß Floyd

Friday, October 06, 2006 7:47:44 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 
Für die Zukunft möchte ich persönlich folgende Datenbanksysteme integriert haben:

dienstgesteuerte DBSe:

- MySQL
- MS SQL Server
- PostgreSQL
- Firebird
- Interbase
- Ingres

Datei-basierende DBSe:

- SQLite
- MSAccess
- Firebird


k00ni

ps.: Welche Version und welche nicht, ist erstmal uninteressant. Aber ich lege das Augenmerk nicht nur auf "New-Stuff", sondern auch auf "ältere" Systeme.

Friday, October 06, 2006 5:25:47 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 
Ich habe mir lange Gedanken darüber gemacht. Und ich denke, wir sollten am Anfang 2-gleisig fahren. Einseits sollten wir die Open-Source-Datenbanksysteme unterstützten. Andererseits auch die komerziellen, speziell aber die, die auch von den "kleinen Leuten" genutzt werden.

Deshalb würde ich MySQL und MS Access angehen. MySQL deshalb, weil ich damit schon seit fast 3 - 4 Jahren mehr oder weniger gearbeitet habe, meist in Verbindung mit PHP. Ich kenne mich dort so aus, das ich schnell und effektiv administrative Aufgaben lösen kann. MS Access wegen der starken Verwendung in privaten Haushalten und in sehr kleinen Firmen.

Später würde ich dann auf MS SQL Server und SQLite gehen, je nachdem, was der Floyd dazu sagt.

Dieser Post ist nur ein Vorschlag und noch nicht endgültig, es darf also diskutiert werden.

Noch eine Anmerkung: Wir sollten versuchen jetzt am Anfang viele "verschiedene" Datenbanksysteme zu integrieren. Liegt daran, dass wir dann später Muster haben, wo wir bei gleichartigen System ansätzen können.
Mit dieser Formulierung meine ich Datenbanksysteme, die einerseits per Dienst betrieben werden (MySQL, PostgreSQL, MSSQL Server). Oder als reines "Ein-Datei"-System, wie beispielsweise SQLite.


k00ni

Friday, October 06, 2006 5:20:12 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 
 Saturday, September 23, 2006
Zu meiner Abwesenheit

Es ist schon eine Weile her, dass ich hier etwas gebloggt habe. Das lag daran, dass ich bei der Bundeswehr meine AGA (Allgemeine Grundausbildung) absolviert habe. Nächste Woche Donnerstag wechsele ich dann den Standort von Bremen (Schwanewede) nach Leipzig (Delitzsch). Während dieser Zeit ist mir kaum möglich gewesen etwas am Quellcode zu basteln. Einerseits hatte ich die ersten Wochen so gut wie keine Zeit. Andererseits war ich so geschafft, dass mir in freien Minuten, die selten waren, einfach die Kraft fehlte, etwas zu programmieren. Da habe ich mich lieber mal ein paar Stunden aufs Ohr gehauen.

Wie dem auch sei, die AGA ist vorbei und nun beginnt das "normale" Soldatenleben. Wie es da mit meiner Zeit aussieht weiß ich nicht. Aber die letzten 2 Wochen habe ich langsam wieder angefangen und am equal-Projekt weitergearbeitet. Ich hoffe, dass ich dass den Rest meiner Wehrdienstzeit auch kann.


Zur Entwicklung des Projektes

In dieser Richtung hat sich einiges getan. Schon vor 3 Monaten konnte man sich aus einer ausgwählten Datenbank alle Tabellen anzeigen lassen, sowie den Inhalt einer bestimmten dazu. Nun arbeite ich daran, dass man neue Tabellen anlegen kann. Dazu habe ich die Bibliothek equal.Objects überarbeitet und neue Objekte hinzugefügt bzw. bestehende modifiziert oder gelöscht.

2 Punkte sind sehr markant bis jetzt:

Einerseits habe ich das Verhalten des Providers geändert. Es sind nun nicht mehr alle Funktionen in einer Klasse zu finden, sondern sind auf 3 aufgeteilt wurden: ConnectionFunctions, TableFunctions und DatabaseFunctions. Damit wird die ganze Sache ressourcenschonender, da bei der Arbeit mit Tabellen nicht unbedingt auch Funktionen für Datenbanken oder Verbindungen braucht. Diese würden nämlich sonst zusätzlich mitgeladen werden.
Andererseits habe ich mich dazu entschlossen, den Kern des Projektes komplett in C# zu schreiben. Dazu gehört der Namespace equal, als auch equal.Objects. Letzteres war erst in Visual Basic verfasst wurden, um dem Floyd etwas entgegen zukommen. Wenn man aber bei der Entwicklung ständig zwischen den Sprachen springen muss, dass bremst dass unnötig. Zusätzlich dazu schreibe ich auch den MySQL 5.0 Povider in C#.

Bei der Portierung des Quellcodes sind mir viele kleine Fehler aufgefallen (inkonsistente Variablennamen, aufgeblähte Klassen etc.), welche ich gleich behoben habe. Ich denke mit diesem Schritt fahre ich bei der Entwicklung besser. Ich hoffe, dass der Floyd es versteht :)


Ein Blick in die Glaskugel


Ich werde die nächsten Stunden damit verbringen, das Anlegen, Modifizieren und Löschen von MySQL 5.0 Tabellen zu implementieren. Als nächster Punkt ist das Anlegen und Löschen von Datenbanken dran. Ist das komplett geschafft, so werde ich dies in Visual Basic .NET für den MS SQL Server portieren. Der Floyd drängte schon am Anfang, dass wir den MS SQL Server mit reinnehmen. Ich werde aber erstmal den 2000er nehmen, da ich denke, dass die 2005er Version noch nicht sehr verbreitet ist.

Vom Projektmäßigen her wars das erstmal von meiner Seite. Ich schätze in ein bis 2 Wochen wird das erledigt sein, je nachdem wie es der Bund zulässt. Stehen die Grundfunktionen des Frameworks, dann wird es auch endlich mal einen Download dazu geben. Aber dazu später mehr, denn im jetzigen Zustand zerballert ihr euch eure Datenbanksysteme nur damit, statt was vernünftiges damit anzustellen.


k00ni

PostSkriptum: Ich spiele mit dem Gedanken, ein Add-In für das VS.NET 2005 zu schreiben, welches das Entwickeln von Anwendungen für das equal-Framework erlaubt.

Saturday, September 23, 2006 9:36:58 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [2]    | 
 Friday, September 15, 2006
Mit nem nun folgenden Script kann man überprüfen ob beim Internetexplorer der PopUp-Blocker aktiviert ist. Sollte der PopUp-Blocker aktiviert sein oder innerhalb des PopUps darf kein JavaScript ausgeführt werden gibt die Funktion "CheckPopUp" "false" zurück, ansonsten "true".

Das Script basiert auf 2 Seiten. Und zwar Seite eins, die aufrufende Seite versucht ein PopUp zu öffnen. Dieses PopUp versucht - insofern es geladen wurde - ein Cookie zu setzten welches die aufrufende Seite wieder auswertet.

Hier erstmal der Code der Seite 1:

    1 <script language=javascript>

    2 function setCookie(name, wert){

    3    document.cookie = unescape(name)+"="+unescape(wert);

    4 }

    5 function getCookie(name){

    6    var i=0;  //Suchposition im Cookie

    7    var suche = name+"=";

    8    while (i<document.cookie.length){

    9       if (document.cookie.substring(i, i+suche.length)==suche){

   10         var ende = document.cookie.indexOf(";", i+suche.length);

   11         ende = (ende>-1) ? ende : document.cookie.length;

   12         var cook = document.cookie.substring(i+suche.length, ende);

   13         return unescape(cook);

   14       }

   15       i++;

   16    }

   17    return null;

   18 }

   19 function CheckPopUp(){

   20    setCookie("popupblocker", "enabled");

   21    var F1 = window.open("checkpopup.html","frmPopUpCheck","width=1,height=1,left=0,top=0");

   22    sleep(100);

   23    F1.close();

   24    return (getCookie('popupblocker')=='enabled');  

   25 }

   26 function doCheckPopUp(){

   27    return getCookie('popupblocker');

   28 }

   29 function sleep(numberMillis){

   30     var exitTime = (new Date()).getTime() + numberMillis;

   31     while (true)

   32     {

   33         if ((new Date()).getTime() > exitTime){return;}

   34     }

   35 }

   36 alert(CheckPopUp());

   37 </script>



Und anschließend den Code der Seite 2 mit dem Name "checkpopup.html":

    1 <script>

    2 function setCookie(name, wert){

    3    document.cookie = unescape(name)+"="+unescape(wert);

    4 }

    5 setCookie("popupblocker", "disabled");

    6 </script>



Ich werde versuchen dieses Funktion auch für den Firefox abzubilden was mir leider bisher noch nicht gelang.

Friday, September 15, 2006 3:55:36 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 
 Thursday, August 31, 2006
So wie versprochen geht es jetzt darum wie man einem Resultset eine fortlaufende Nummer zuweist.
Leider geht dies mit MSSQL boardmitteln nicht wodurch ich gezwungen war eine wenig zu improvisieren. Im Artikel Temporäre Tabellen anlegen und löschen habe ich bereits beschrieben wie man temporäre Tabellen anlegen kann. Dieses Prinzip mach ich mir jetzt zu nutze.

Hier jetzt erstmal das komplette Statement:

/*Prüfen ob die Tabelle "#tblTemp" schon exsistiert - wenn ja löschen
IF not OBJECT_ID('tempdb..#tblTemp') IS NULL
begin
    drop table [#tblTemp]
end

/*Temporäre Tabelle "#tblTemp" anlegen
create table #tblTemp(
    [a_id] [int] IDENTITY (1, 1) NOT NULL ,
    [a_Spalte1] [int],
    [a_Spalte2] [varchar])
go

/*Temporäre Tabelle "#tblTemp" mit Werten füllen*/
insert into #tblTemp (a_spalte1,a_Spalte2)
    select a_spalte1,a_Spalte2 from tblQuelle --Das Selectstatement das mit einer fortlaufenden Nummer angezeigt werden soll

/*Temporäre Tabelle "#tblTemp" auslesen
select * from #tblTemp


So was passiert hier:
Im ersen Schritt wird geprüft ob die Tabelle #tblTemp schon exsistiert. Wenn ja wird diese wieder gelöscht (ist nur zur Sicherheit).
Der zweite Schritt legt die Tabelle #tblTemp an und fügt die benötigten Spalten hinzu. Hierbei bitte ich um besonderes augenmerk auf die Spalte a_id. Diese wird anschließend unsere fortlaufende Nummer enthalten.
Im Schitt 3 wird die Tabelle nun gefüllt wobei als Quelle das eigendliche Statement ausgeführt wird.
Und im Schritt 4 wird #tblTemp wieder ausgelesen.

Das Resultset könnte dann so aussehen:

a_id a_Spalte1     a_Spalte2
---- ------------ ------------
1     11111          Leipzig
2     22222          Berlin
3     33333          München

Zwar ist dieser weg sehr umständlich aber der einzig mir bekannte Weg.

Eine Möglichkeit um möglichst viele Spalten zu Select jedoch nicht alle Spalten in der virtuellen Tabelle aufnehmen zu müssen wäre die, das man nur die Zählerspalte (a_id) und eine ReferenzID-Spalte anleget und anschließend die Quelltabelle mit der temporären Tabelle anhand der ReferenzID-Spalte join't.

Thursday, August 31, 2006 10:09:29 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [2]    | 
Wer sich intensiver mit SQL beschäftigen muss der wird hin und wieder das Problem habe das er Daten innerhalb eine Stored Procedure Daten zwischenspeichen muss. Hierfür bieten sich temporäre Tabellen an.

Temporöre Tabellen sind Tabellen die nur im Speicher des SQL-Servers verfügbar sind. Sie werden nicht langfristig auf dem SQL-Server angelegt. Es gilt dabei zwei verschiedene Arten von temporöre Tabellen zu unterscheiden. Zum einen wären das die Sessionbeasierenden temporäre Tabellen. Diese sind nur innerhalb einer Sitzung verfügbar bzw. können nur innerhalb der Stored Procedure verwendet werden die sie erstellt hat. Wobei hierbei zu beachten ist das wenn eine Stored Procedure eine anderen aufruft die aufgerufene Stored Procedure innerhalb der Session der aufrufenden läuft und somit alle Sessionbeasierenden temporäre Tabellen übernimmt. Eine Sessionbeasierenden temporöre Tabellen legt man an in dem man ein # vor den Namen der Tabelle setzt.
Die zweite Art von temporäre Tabellen sind die globalen temporöre Tabellen. Diese stehen allen Statements für eine gewissen Zeitraum zur Verfügung und sind nicht abhängig von einer Session. Eine globale temporäre Tabellen legt man an in dem man zwei ## vor den Namen der Tabelle setzt.

In diesem Beispiel verwende ich Sessionbeasierenden temporöre Tabellen.

Hier ein Beispiel wie man eine solche Tabelle anlegt:

/*Temporäre Tabelle "#tblTemp" anlegen
create table #tblTemp(
    [a_id] [int] IDENTITY (1, 1) NOT NULL ,
    [a_Spalte1] [int],
    [a_Spalte2] [varchar])
go


Löschen funktioniert eben so einfach:

/*Prüfen ob die Tabelle "#tblTemp" schon exsistiert - wenn ja löschen
IF not OBJECT_ID('tempdb..#tblTemp') IS NULL
begin
    drop table [#tblTemp]
end


Im nächsten Artikel werde ich diese temporären Tabellen verwenden um einem Resultset eines Select-Stament eine Vortlaufenden Nummer zuzuweisen.


Thursday, August 31, 2006 9:50:28 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]    | 
 Thursday, August 10, 2006
Hallo,

ich brauch mal eure Hilfe!! Und zwar hab ich ein sehr interesantes Problem. Ich weiß nicht ob ihn ankhsvn kennt. Das ist ein Visual Studio Addin für SVN. Die haben das Contextmenü des SolutionExplorers um einen Eintrag erweitert - siehe hier:



Die interessante Frage ist, wie haben die es gemacht?! Ich brauch das für ein eigenes Addin was ich grade schreiben will. Aus dem Source-Code werd ich nicht wirklich schlau.
Hat wer ne Idee wo ich suchen könnte bzw. wonach?

Gruß Floyd

Thursday, August 10, 2006 1:59:41 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [4]    |