Announcement

Collapse
No announcement yet.

Float-Spalte beim Export auf 2 Stellen runden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Float-Spalte beim Export auf 2 Stellen runden

    Hallo zusammen,

    ich muss mich nochmals an euch wenden, weil ich folgende herausforderungen bis dato nicht meistern konnte:

    den nachfolgenden code habe ich im internet gefunden. er dient dazu eine datenbank (ms sql 2005) in eine excel-datei zu exportieren. eine datenbank wird in ein excelfile abgelegt, die enthaltenen tabellen finden sich anschliessend in den tabellenblätter wieder.
    ich kenne mich zu wenig mit sql server 2005 aus, um den code vollständig zu verstehen. er funktioniert bei mir eigentlich sehr gut, allerdings möchte ich noch vier verbesserungen/veränderungen vornehmen - und weiss nicht genau wie:

    1. Sobald der Ausgabepfad ein Leerzeichen beinhaltet, wird am Ende der Prozedur die erstellte Access-Datenbank nicht wieder gelöscht. Da ich (mit Hilfe eines Java-Programms) dynamisch sehr umfangreiche SQL-Files erstellen lasse, welche anschliessend Datenbanken erzeugen und diese dann in Excel-Dateien geschrieben werden, kann es trotzdem recht störend sein, wenn jedes Mal 30 Access-Datenbanken zusätzlich zu den 30 Excels erstellt werden. Diese müssen dann von Hand gelöscht werden.
    Wie gesagt: Wenn keine Leerzeichen im Ausgabepfad sind, funktioniert das Löschen der Access-Dateien reibungslos.

    2. Würde ich gerne alle Spalten vom Datentyp float auf zwei Nachkommastellen runden. Wie lässt sich dies am besten lösen?
    Oder muss ich tatsächlich vor dem Exportieren die Datentypen der Datenbanken auf zwei Nachkommastellen setzen ? (Wichtigste Frage)


    3. Gibt es eine Möglichkeit das zu erstellende Excel vom SQL-Code aus in irgendeiner Weise zu formatieren? Z.b. die erste Zeile in fetter Schrift oder aber auch die ersten beiden Spalten sollten etwas breiter sein als per default... etc.?

    4. Eine Knacknuss: Es kann vorkommen, dass eine Tabelle mehr als 256 Spalten beinhaltet - und somit über den Grenzwert von MS Excel Dateien (256 Spalten) steigt. Damit wird keine Exceldatei erstellt, sondern eine Fehlermeldung erzeugt. Gibt es eine Möglichkeit, dass der Server automatisch - sobald mehr als 256 Spalten - den Export in zwei Exceltabellenblätter vornimmt. Allerdings müsste hierbei auf der Exceltabelle die eindeutige Id jeder Entität nochmals ausgegeben werden. Bin mir nicht sicher, ob es hierfür eine Lösung gibt.

    Weiss jemand, wie ich obengenannte Herausforderungen in den Griff bekommen könnte?
    Ich freue mich über jeden Vorschlag.
    Vielen Dank
    Barbara

    Code:
    DECLARE @pfad varchar(255)  
     SET @pfad = D:\IrgendeinOutputpfad\'  
     DECLARE @hr int             -- Returncode der sp_OA... Aufrufe  
     DECLARE @katalog int        -- Objektvariable für ADOX.Catalog  
     DECLARE @verbindung int     -- Objektvariable für ADO.Connection  
     DECLARE @dbname varchar(255) -- Name der temporären Access-Datenbank  
     DECLARE @conString varchar(512)  -- Verbindungszeichenfolge für Access-Datenbank  
     DECLARE @quelle varchar(255)       -- Hilfsfeld für Fehlerbehandlung  
     DECLARE @beschreibung varchar(255)      -- Hilfsfeld für Fehlerbehandlung  
     DECLARE @dummy int              -- Dummy Output Parameter  
     DECLARE @Excel_Mappe varchar(255)  -- Vollständiger Name der Ziel Excelmappe  
     DECLARE @tabelle varchar(255)      -- Name der zu exportierenden Tabelle  
     DECLARE @besitzer varchar(255)     -- Besitzer der zu exportierenden Tabelle  
     DECLARE @exec varchar(4000)        -- Hilfsvariable für dynamische Ausführungen  
       
     -- Cursor zum Ermitteln aller Tabellen ohne Text- und Image-Spalten  
     DECLARE curTabellen CURSOR FAST_FORWARD FOR   
      SELECT t.TABLE_SCHEMA, t.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES t  
      WHERE TABLE_TYPE = 'BASE TABLE'  
      AND NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS  
         WHERE DATA_TYPE IN ('text', 'ntext',  'image')  
         AND TABLE_CATALOG = t.TABLE_CATALOG AND  
               TABLE_SCHEMA = t.TABLE_SCHEMA AND  
                                  TABLE_NAME = t.TABLE_NAME)  
        ORDER BY TABLE_NAME  
       
     -- Erzeugen eines ADOX-Katalog Objekts  
     EXEC @hr = master.dbo.sp_OACreate 'ADOX.Catalog', @katalog OUTPUT  
     IF @hr <> 0  -- Fehlerbehandlung  
      BEGIN  
       EXEC sp_OAGetErrorInfo @katalog, @quelle OUTPUT, @beschreibung OUTPUT  
       RAISERROR ( 'Fehler beim Erstellen des ADOX.Catalog Objekts: %s', 10 , -1, @beschreibung)  
      END  
       
     -- Zufälliges Erzeugen eines Datenbank-Namens  
     SET @dbname = @pfad +  CAST(newid() AS varchar(100)) + '.MDB'  
     -- Erstellen der Verbindungszeichenfolge  
     SET @conString = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' + @dbname  
       
     -- Erstellen einer neuen (leeren) Access-Datenbank  
     -- Dieser Schritt ist notwendig, da nur über eine Verbindung zu einer Access-Datenbank  
     -- die benötigte Jet-Funktionalität zur Verfügung steht  
     EXEC @hr = master.dbo.sp_OAMethod @katalog, 'Create',   
              @dummy output,  
             @conString  
     IF @hr <> 0  -- Fehlerbehandlung  
      BEGIN  
       EXEC sp_OAGetErrorInfo @katalog, @quelle OUTPUT, @beschreibung OUTPUT  
       RAISERROR ( 'Fehler beim Erstellen der Access-Datenbank %s: %s', 10 , -1, @dbname, @beschreibung)  
      END  
       
     -- Variable @verbindung auf die Eigenschaft "ActiveConnection" des Katalog-Objekts setzen  
     EXEC @hr = master.dbo.sp_OAGetProperty @katalog, 'ActiveConnection', @verbindung OUTPUT  
     IF @hr <> 0  -- Fehlerbehandlung  
      BEGIN  
       EXEC sp_OAGetErrorInfo @verbindung, @quelle OUTPUT, @beschreibung OUTPUT  
       RAISERROR ( 'Fehler beim Zugriff auf Access-Datenbank %s: %s', 10 , -1, @dbname, @beschreibung)  
      END  
       
     -- Öffnen des Cursors und Export für alle gefundenen Tabellen durchlaufen  
     OPEN curTabellen  
     FETCH NEXT FROM curTabellen INTO @besitzer, @tabelle  
     WHILE @@FETCH_STATUS = 0  
     BEGIN  
      -- Dynamisches Erzeugen der SELECT INTO Anweisung  
      SET @exec = 'SELECT TOP 65535 * INTO [Excel 8.0;Database=' + @pfad + db_name() + '.xls].[' + @besitzer + '_' + @tabelle + '] FROM [ODBC;Driver=SQL Server;Database=' + DB_NAME() + ';Server=' + @@SERVERNAME + ';Trusted_Connection=Yes;].[' + @besitzer + '.' + @tabelle + ']'  
      EXEC @hr = master.dbo.sp_OAMethod @verbindung, 'Execute', @dummy output, @exec  
      IF @hr <> 0  -- Fehlerbehandlung  
       BEGIN  
        EXEC sp_OAGetErrorInfo @verbindung, @quelle OUTPUT, @beschreibung OUTPUT  
        RAISERROR ( 'Fehler beim Export: (%s): %s', 10 , -1, @exec, @beschreibung)  
       END  
      FETCH NEXT FROM curTabellen INTO @besitzer, @tabelle  
     END  
       
     -- "Aufräumarbeiten"  
     CLOSE curTabellen  
     DEALLOCATE curTabellen  
       
     EXEC @hr = master.dbo.sp_OAMethod @verbindung, 'Close'  
     IF @hr <> 0  -- Fehlerbehandlung  
       BEGIN  
        EXEC sp_OAGetErrorInfo @verbindung, @quelle OUTPUT, @beschreibung OUTPUT  
        RAISERROR ( 'Fehler beim Schliessen der Verbindung zur Access-Datenbank:  %s', 10 , -1,  @beschreibung)  
       END  
     EXEC @hr = master.dbo.sp_OADestroy @verbindung  
     IF @hr <> 0  -- Fehlerbehandlung  
       BEGIN  
        EXEC sp_OAGetErrorInfo @verbindung, @quelle OUTPUT, @beschreibung OUTPUT  
        RAISERROR ( 'Fehler beim Zerstören des ADO-Connection Objekts:  %s', 10 , -1,  @beschreibung)  
       END  
     EXEC @hr = master.dbo.sp_OADestroy @katalog  
     IF @hr <> 0  -- Fehlerbehandlung  
       BEGIN  
        EXEC sp_OAGetErrorInfo @verbindung, @quelle OUTPUT, @beschreibung OUTPUT  
        RAISERROR ( 'Fehler beim Zerstören des ADO-Connection Objekts:  %s', 10 , -1,  @beschreibung)  
       END  
     -- Temporäre Access-Datenbank löschen  
     SET @exec = 'DEL ' + @dbname  
     EXEC master.dbo.xp_cmdshell @exec ,NO_OUTPUT
    GO
    Zuletzt editiert von barbara83; 05.08.2008, 01:46.

  • #2
    Hallo Barbara,

    viel helfen werden ich Dir nicht können, nur ein paar Kleinigkeiten:

    zu 1) Das ist zum Glück leicht. Es wir ein DOS Command "DEL" abgsetzt. Wenn im Dateinamen ein Leerzeichen enthalten ist, muss der Name komplett in Anführungszeichen gesetzt werden; also ganz am Ende wie folgt ändern

    -- Temporäre Access-Datenbank löschen
    SET @exec = 'DEL "' + @dbname +'"'
    EXEC master.dbo.xp_cmdshell @exec ,NO_OUTPUT

    zu 2) Im SELECT Statement kannst Du runden lassen mit
    SELECT ROUND(1.2345, 2)
    Nur da Du mit SELECT * arbeitest, hilft es Dir vorerst nicht weiter.

    zu 4) Ist von mir nicht ernst gemeint, aber verwende Excel 2007, damit hast Du das Problem nicht ;-)
    Olaf Helper

    <Blog> <Xing>
    * cogito ergo sum * errare humanum est * quote erat demonstrandum *
    Wenn ich denke, ist das ein Fehler und das beweise ich täglich

    Comment


    • #3
      hallo olaf,

      danke für deine tipps.
      1) konnte ich - wie angegeben - lösen. super!

      2) habe ich auch gelöst, indem ich schon bei der erstellung der spalten darauf achtete, dass nur zwei stellen angegeben werden mit decimal [18, 2] als datentyp.
      gibt es vielleicht einen besseren datentyp. die meisten zahlen gehen vor dem komma nicht über 100.

      3) konnte ich noch nicht lösen, wird wahrscheinlich auch nicht möglich sein aus dem sql server heraus... !?

      4) problem auch noch nicht gelöst.
      gibt es echt in office 2007 keine beschränkung der anzahl spalten mehr oder ist die zahl viel grösser? wie gross, wo liegt die grenze?
      würde das selbe skript für die excelerstellung auch für die 2007ner version funktionieren oder müsste man dieses adaptieren? ich habe das office 2007 auch, jedoch noch nicht installiert, da keine zeit die neue oberfläche zu erlernen.

      ich habe noch eine weitere frage zu einem merkwürdigen verhalten von ms sql server:

      wie gesagt, benutze ich ein java tool, um sql-dateien zu generieren. dies funktioniert eignetlich ganz gut. ich gehe dann immer so vor, dass ich die gleiche sql-datei überschreibe und dann wieder im sql server ausführe. wird die sql datei extern (ausserhalb vom sql server managementstudio) verändert, popt jeweils ein dialogfenster auf, um die datei im sql server zu aktualiseren. dieser funktion bediene ich mich dann fast immer. komischerweise kommt es ab und an vor, dass sonderzeichen nicht mehr erkannt werden. so wird dann beispielsweise ein "ä" oder ein "ö" als rhombus mit fragezeichen drin dargestellt.
      dies kann zu abfragefehlern führen (besserer fall) oder aber der code kann ausgeführt werden ohne probleme anzuzeigen, aber in den where-klauseln treffen dann abfragen nicht mehr zu.
      z.b. WHERE [Geschlecht] = 'männlich' wird zu WHERE [Geschlecht] = 'm?nnlich'

      hier gibt es dann natürlich keine treffer mehr. und dies kann dann auch unbemerkt von statten gehen. daher ist dieser fall sehr unglücklich.

      wenn ich das managementstudio anschliessend schliesse und die datei noch einmal öffne, werden die sonderzeichen wieder korrekt dargestellt. daher muss das problem irgendwo beim managementstudio liegen.

      hat jemand eine idee, wie dieser fall verhindert werden kann?

      vielen dank und viele grüsse
      barbara

      Comment


      • #4
        2) Du kannst bei DECIMAL eine fast beliebige Genauigkeit angeben, also auch DECIMAL(4, 2)

        3) Nein, auf die Art kannst Du nur Daten in die Excel-Tabelle schreiben, aber keine Formatierung vornehmen.

        4) Auf dieser Welt ist alles deterministisch und somit beschränkt.
        MS hat die Einschränkung auf 16K Spalten und 1M Zeilen erhöht (wer will so eine Tabelle noch arbeiten, ohne den Überblick zu verlieren?)

        Alles im allen mutet mir Dein Weg / Lösung doch etwas merkwürdig an.

        - Wieso schreibst Du das SQL in eine Datei und lässt es im MMS ausführen (ziemlicher Umweg)? Es gibt für den SQL Server auch JDBC Treiber => aus Deinem Java Programm eine Connection öffnen und dann direkt das SQL Statement ausführen; fertig und Du hast kein Problem mit den Umlauten/Sonderzeichen

        - Wegen der Formatierung, wenn die Tabellen (+ Felder) halbwegs feststehen, würde ich es "statisch" lösen über Vorlage-Excel Dateien, die die Formatierung enthalten. Die dann kopieren und die Daten reinschreiben.
        In dem Fall kann das schreiben auch einfacher direkt aus SQL Server heraus ohne Umweg über ActiveX + Access erfolgen.
        Olaf Helper

        <Blog> <Xing>
        * cogito ergo sum * errare humanum est * quote erat demonstrandum *
        Wenn ich denke, ist das ein Fehler und das beweise ich täglich

        Comment


        • #5
          hallo olaf

          danke nochmals für deine antwort.

          eigentlich wollte ich die abfragen auch aus dem java programm heraus erstellen, allerdings traf ich dabei auf die folgenden beiden probleme:

          1. Meine SQL-Dateien erstellen Tabellen und Datenbanken, Benutzen diese Skripts, um ins Excel zu exportieren etc. Ich brauche also T-SQL und anderes. Viele Befehle konnte ich irgendwie nicht gegen den Server schicken, da es nicht einfach die normalen SQL-Queries sind, sondern beispielsweise Schlüsselwörter wie GO darin vorkommen, welche offenbar nicht mit der JDBC Verbindung ausgeführt werden können.
          Ich weiss nicht - kenne mich darin ja eigentlich überhaupt nicht aus- aber ich konnte jedenfalls keinen Weg finden. Vielleicht belehrst Du mich eines Besseren?

          2. Da meine Software noch nicht vollständig ausgetestet ist, kommt es ab und an zu Abfragefehlern (häufig noch im Zusammenhang mit Sonderzeichen, z.b. darf ein Ordner in Windows kein ":" (Doppelpunkt) etc enthalten. Die Software wird von mir jedoch schon für Berechnungen eingesetzt. Es ist dann jeweils hilfreich, zu sehen, ob der Server eine Fehlermeldung erzeugt hat oder ob alles reibungslos funktionierte.
          Denke, dass sich dieses Problem irgendwie lösen lässt - selber weiss ich aber nicht, wie ich die Meldungen in mein Java Programm bekommen würde (die Meldungsliste ist jeweils sehr lang, siehe Bsp. unten):

          Code:
          (12816 Zeile(n) betroffen)
          
          (12816 Zeile(n) betroffen)
          
          (12816 Zeile(n) betroffen)
          
          (12816 Zeile(n) betroffen)
          
          (12816 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (181 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (202 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (12816 Zeile(n) betroffen)
          
          (3 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (21 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (3 Zeile(n) betroffen)
          
          (21 Zeile(n) betroffen)
          
          (3 Zeile(n) betroffen)
          
          (165 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (42 Zeile(n) betroffen)
          
          (42 Zeile(n) betroffen)
          
          (42 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (42 Zeile(n) betroffen)
          
          (42 Zeile(n) betroffen)
          
          (42 Zeile(n) betroffen)
          
          (0 Zeile(n) betroffen)
          
          (165 Zeile(n) betroffen)
          
          (3 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (2 Zeile(n) betroffen)
          
          (3 Zeile(n) betroffen)
          
          (3 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (8 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (8 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (54 Zeile(n) betroffen)
          
          (55 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (55 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)
          
          (7 Zeile(n) betroffen)
          
          (1 Zeile(n) betroffen)

          - Wegen der Formatierung, wenn die Tabellen (+ Felder) halbwegs feststehen, würde ich es "statisch" lösen über Vorlage-Excel Dateien, die die Formatierung enthalten. Die dann kopieren und die Daten reinschreiben.
          In dem Fall kann das schreiben auch einfacher direkt aus SQL Server heraus ohne Umweg über ActiveX + Access erfolgen.
          Aber dann muss ich es für jede Exceldatei von Hand machen, oder?

          Weil so eine Abfrage kann schon mal 20 Excels (entspricht den erstellten Datenbanken) mit jeweils meheren Tabellenblättern (entspricht den ursprünglichen Tabellen in der Datenbank) generieren.

          Mfg
          Barbara

          Comment


          • #6
            Hallo Barbara,

            was geschieht den weiter mit den Excel-Dateien bzw. was sind die genauen Anforderungen an das Ergebnis als Excel?
            Ändert sich der Aufbau/Selektion/Anzahl etc. häufiger oder steht das eigentlich halbwegs fest?

            Ich frage, weil es wie häufig für ein Problem mehrere Lösungsmöglichkeiten gibt.

            Z.B. kann man aus Excel heraus auch direkt auf die Daten vom SQL Server zugreifen (über Externe Daten => Abfrage).
            Man kann sogar so auf "Live"-Daten zugreifen, d.h. Excel merkt sich den Connect und kann dann einfach die Daten aktualisieren lassen.
            Ist nur schlecht, wenn man dan die XLS an extern oder an User gibt, die keinen Zugriff auf SQL Server haben.

            Die schon erwähnte Variante mit den Vorlagen ist eine weitere Möglichkeit. Zugegeben, das ist zunächst ein echter Aufwand, aber den hat man nur einmal.
            Dann kann man sogar direkt aus dem SQL Server in die Excel-Datei schreiben lassen, das sieht dann z.B. so aus:
            [highlight=SQL]INSERT INTO
            OPENROWSET('Microsoft.Jet.OLEDB.4.0',
            'Excel 8.0;Database=C:\testing.xls;',
            'SELECT NameX, DateX FROM [Tabelle1$]')
            SELECT 'Test', GETDATE() [/highlight]

            zu 1 + 2) Ich habe noch nicht mit dem JDBC Treiber gearbeitet, aber er sollte eigentlich das SQL Statement 1:1 an den Server durchreichen und es nicht selbst interpretieren.
            Wenn Du die Ergebnisse (Anzahl Datensätze) benötigst, muss Du wohl oder übel jedes Statement separate ausführen und die "EffectedRecordsets" auswerten.
            Zuletzt editiert von O. Helper; 07.08.2008, 09:15.
            Olaf Helper

            <Blog> <Xing>
            * cogito ergo sum * errare humanum est * quote erat demonstrandum *
            Wenn ich denke, ist das ein Fehler und das beweise ich täglich

            Comment


            • #7
              hallo olaf

              ach, jetzt verstehe ich, was du in diesem zusammenhang mit "vorlage" meinst.

              nun, das java programm erzeugt den sql code dynamisch aufgrund von benutzerabfragen (jdbc mässig gelöst). D.h. der Benutzer kann genau festlegen, für welche objekte / elemente ein excel mit welchen zeilen und spalten (etc.) erstellt werden soll. aus diesem grund kann es vorkommen, dass nur ein excel mit einer zeile und einer spalte oder aber auch 35 excels mit je 20 tabellenblättern an je 30 spalten und 100 zeilen erzeugt werden (vereinfachtes, etwas überspitztes beispiel). Diese Excels werden nicht nur auf dem Rechner mit Serverzugriff geöffnet und weiterverwendet.
              daher denke ich, dass einzig der umweg über activeX zum ziel führt.

              im moment ist der ablauf folgendermassen:

              1. benutzer öffnet java-tool, stellt parameter ein und erzeugt anschliessend eine sql-datei.

              2. Ein zweites Icon ermöglicht es dem Benutzer diese Datei (immer am gleichen ort mit gleicher bezeichnung gespeichert) per knopfdruck zu öffnen (gelöst mit einer .bat; batch-datei:
              start C:\irgendeinordner\sql-datei.sql
              exit

              3. Anschliessend muss der Benutzer noch beim Server (Management Studio) auf Ausführen klicken und die gewünschten excels werden erstellt.

              Vielleicht könnte man die Schritte 2 & 3 noch vereinfachen. Möglicherweise lässt sich so etwas aus dem java-tool heraus starten!???
              Gibt es irgendeine Möglichkeit dem mitzuteilen, dass er sofort eine sql-Datei ausführen soll (ohne noch manuell auf ausführen klicken zu müssen), z.b. irgendwie mit einer .bat-Datei??

              Comment


              • #8
                ich habe jetzt in sqlcmd.exe eine möglichkeit gefunden, um schritt 2 und 3 zusammenzufassen:

                Code:
                "C:\Programme\Microsoft SQL Server\weitererpfad\SQLCMD.EXE" -i "C:\pfad\sql-datei.sql"
                
                pause
                So sehe ich dann im dos fenster im prinzip genau die meldungen des servers (10 zeilen betroffen etc.)

                Sieht schon mal sehr gut aus.

                Allerdings stört mich daran noch eine kleinigkeit, die sich möglicherweise beheben lässt:

                Bei den Meldungen wird jeweils ausgegeben, wenn der Datenbankkontext geändert wurde:

                "Der Datenbankkontext wurde auf 'master' geändert"

                Dies ist im Prinzip nicht schlecht, nur wäre es für mich persönlich praktischer, wenn (in der jetzigen Phase) solche Meldungen unterbleiben könnten, um beim Durchscrollen sofort Fehlermeldungen erkennen zu können...
                Die Meldung des Datenbankkontext sieht beim schnellen Durchscrollen wie eine Fehlermeldung aus.

                Gibt es hier eine Möglichkeit?


                Nun, ich suche mal nach einer Möglichkeit, um die bat-Datei aus Java heraus auszuführen - dann hätten wir die ganze Geschichte in einem Schritt verpackt.

                Grüsse und Dank für die Hilfe
                Barbara

                Comment


                • #9
                  so,

                  habe jetzt eine lösung, bei welcher das java-tool in einem ersten schritt eine sql-datei erstellt, anschliessend eine korrespondierende .bat-Datei. Der Batch wird anschliessend automatisch vom Java Programm angestossen und der Benutzer / die Benutzerin bekommt die SQL-Meldungen in einem Dos-Fenster mitgeteilt. Damit bleibt ihm / ihr einiges an mühsamen Klickaufgaben erspart.
                  Danke für den Input. @ Olaf


                  Was mich aber dabei immer noch stört:

                  ich habe jetzt in sqlcmd.exe eine möglichkeit gefunden, um schritt 2 und 3 zusammenzufassen:


                  Code:
                  "C:\Programme\Microsoft SQL Server\weitererpfad\SQLCMD.EXE" -i "C:\pfad\sql-datei.sql"
                  
                  pause
                  So sehe ich dann im dos fenster im prinzip genau die meldungen des servers (10 zeilen betroffen etc.)

                  Sieht schon mal sehr gut aus.

                  Allerdings stört mich daran noch eine kleinigkeit, die sich möglicherweise beheben lässt:

                  Bei den Meldungen wird jeweils ausgegeben, wenn der Datenbankkontext geändert wurde:

                  "Der Datenbankkontext wurde auf 'master' geändert"

                  Dies ist im Prinzip nicht schlecht, nur wäre es für mich persönlich praktischer, wenn (in der jetzigen Phase) solche Meldungen unterbleiben könnten, um beim Durchscrollen sofort Fehlermeldungen erkennen zu können...
                  Die Meldung des Datenbankkontext sieht beim schnellen Durchscrollen wie eine Fehlermeldung aus.


                  Gibt es hier eine Möglichkeit?

                  Comment


                  • #10
                    Hallo Barbara,

                    wie gesagt, für jedes Problem gibt es viele Lösungen; da hast Du noch eine gefunden.

                    Wie die Ausgabe des Kontext-Switch unterbunden werden kann, ist mir nicht bekannt; was nicht heissen soll, das es nicht irgendwie eine Möglichkeit gibt.

                    Aber da Du gezielt auf der Suche nach Fehlermeldungen bis: Es gibt eine Option sich die Fehlermeldungen separat (also ohne die Results) ausgeben zu lassen. Dafür gibt es die Option

                    :Error < filename >| STDERR|STDOUT

                    Wenn Du also im generierten SQL Script noch in die erste Zeile

                    :Error SQLError.txt
                    GO


                    ausgibst, werden alle Fehlermeldungen in die Textdatei umgeleitet (sind also in der regulären Ausgabe nicht sichtbar). So eine Meldung sieht dann z.B. so aus:

                    Meldung '208', Ebene '16', Status '1', Server 'MyServer\Instance', Zeile 4
                    'Ungültiger Objektname 'Tabelle'.'


                    also auch mit der Zeilenummer, wo der Fehler auftrat. Analog kann man auch das Result umleiten lassen mit:

                    :Out < filename>| STDERR| STDOUT
                    Olaf Helper

                    <Blog> <Xing>
                    * cogito ergo sum * errare humanum est * quote erat demonstrandum *
                    Wenn ich denke, ist das ein Fehler und das beweise ich täglich

                    Comment


                    • #11
                      hallo olaf

                      danke für deine antwort.
                      wäre eine gute möglichkeit, um fehler zu tracken.
                      allerdings bringe ich es nicht auf die Reihe die Einstellung in mein Skript einzubauen:

                      Also

                      :Error <pfad>
                      GO

                      müsste in meiner erzeugten SQL-Datei ganz oben stehen, oder?

                      Ich kriege dabei immer folgende Fehlermeldung:

                      Meldung 102, Ebene 15, Status 1, Zeile 1
                      Falsche Syntax in der Nähe von ':'.
                      Entferne ich das Doppelpunkt:
                      Meldung 2812, Ebene 16, Status 62, Zeile 1
                      Die gespeicherte Prozedur 'ERROR' wurde nicht gefunden.
                      Wie genau müsste der Code aussehen, um beispielsweise in die Datei
                      C:\Meine Daten\sqlerror.txt
                      umzuleiten?

                      Muss ich vielleicht beim Server zuvor noch irgendeine Einstellung ändern?

                      Angenommen es würde funktionieren, würden Fehler beim Schreiben ins Excel ausgegeben werden? Solche:

                      Fehler beim Erstellen der Access-Datenbank C:\!\hallo\6F22680B-226B-40CB-B409-FA5E11BC057C.MDB: 'C:\!\hallo\6F22680B-226B-40CB-B409-FA5E11BC057C.MDB' ist kein zulässiger Pfad. Stellen Sie sicher, dass der Pfad richtig eingegeben wurde und dass Sie mit dem Server, auf dem sich die Datei befindet, verbunden sind.

                      Fehler beim Zugriff auf Access-Datenbank C:\!\hallo\6F22680B-226B-40CB-B409-FA5E11BC057C.MDB: Typkonflikt.

                      Fehler beim Export: (SELECT TOP 65535 * INTO [Excel 8.0;Database=C:\!\hallo\Total.xls].[dbo_Ressort] FROM [ODBC;Driver=SQL Server;Database=Total;Server=MULTIMEDIA;Trusted_Co nnection=Yes;].[dbo.IrgendeineTabelle]): Syntax für sp_OAMethod: ObjPointer int IN, MethodName varchar IN [, @returnval <any> OUT [, zusätzliche IN-, OUT- oder BOTH-Parameter]].
                      Weil beim Management Studio wird da jedes Mal angegeben "Abfrage erfolgreich durchgeführt"!?


                      Noch eine dritte kleine Frage:
                      Ich habe ein Feld Datum vom Typ smalldatetime. Mein JavaProgramm liest die Ausprägungen wie folgt:

                      '2006-11-29 00:00:00.0'

                      Es werden dann Filter erstellt:

                      Code:
                      SELECT irgendetwas 
                      FROM tabelle
                      WHERE[Datum] = '2006-11-16 00:00:00.0'
                      Dies ergibt folgenden Fehler:

                      Meldung 296, Ebene 16, Status 3, Zeile 5
                      Bei der Konvertierung des char-Datentyps in den smalldatetime-Datentyp liegt der smalldatetime-Wert außerhalb des gültigen Bereichs.
                      Die Abfrage funktioniert mit :
                      Code:
                      SELECT irgendetwas 
                      FROM tabelle
                      WHERE[Datum] = '20061116'
                      Aber dann muss ich meinem Javaprogramm irgendwie noch beibringen, dass es allen Ausprägungen bei Spalten vom typ smalldatetime genau dieses Format zuweist. Ist recht schwierig.
                      Gibt es vielleicht eine bessere Lösung dafür?

                      Danke und Gruss
                      Barbara

                      Comment


                      • #12
                        Wie/Wo hast Du es ausgeführt?
                        Die :ERROR Anweisung funktioniert nur, wenn der SQL Batch mit SQLCMD ausgeführt wird, nicht im Management Studio-Query!!!

                        Auch auf dem Weg wirst Du nur die Fehler vom SQL Server selber erhalten, nicht von dem, was "ausserhalb" abläuft.

                        Eine implizite Typkonvertierung sollte man möglichst immer vermeiden, das geht meistens schief. Besser ist explizit und da kannst Du das Format, das übergeben wird, auch angeben, z.B.:

                        select convert(smalldatetime, '2006-11-16 00:00:00.0', 121)

                        121 steht Kanonisch = yyyy-mm-dd hh:mm:ss.sss
                        104 wäre für die DE übliche Formatierung.
                        Olaf Helper

                        <Blog> <Xing>
                        * cogito ergo sum * errare humanum est * quote erat demonstrandum *
                        Wenn ich denke, ist das ein Fehler und das beweise ich täglich

                        Comment


                        • #13
                          Hallo Olaf

                          Danke, jetzt habe ich es verstanden und konnte es auch umsetzen.
                          Hatte es im Management Studio getestet.

                          Das funktioniert schon mal super.

                          Wenn ich nun sowohl out als auch error in die selbe datei leite, dann werden zuerst die "normalen meldungen ausgegeben" und anschliessend die errors.

                          könnte man dies umkehren, so dass zuerst die errors erscheinen?
                          falls es nicht geht, kein problem.



                          das mit den datumstypen verstehe ich immer noch nicht vollständig. d.h. deiner meinung nach sollte ich bereits beim abfragen (wenn das java tool die daten beim server holt) darauf achten, dass das datum korrekt daher kommt.

                          im moment werden ausprägungen einer tabelle wie folgt aus java heraus abgefragt:

                          ("USE " + datenbankname + "; SELECT DISTINCT [" + merkmal + "] FROM " + tabellenname + ";"));

                          dann müsste ich dort so etwas einbauen wie :

                          Code:
                          use datenbankname
                               wenn merkmal = vom typ smalldatetime (oder sonstiger datumstyp)
                                     select distinct ExpliziteKonvertierung(merkmal) FROM tabellenname
                              wenn merkmal != vom typ smalldatetime (oder sonstiger datumstyp)
                                     select distinct merkmal from tabellenname
                          Oder?
                          Wie müsste der Teil ExpliziteKonvertierung(merkmal) aussehen, damit das datum in der form "20080512" daherkommt? dann könnte ich gleich damit die filter erstellen im javatool?

                          gruss barbara

                          Comment


                          • #14
                            Ich glaube nicht, das man die Reihenfolge umdrehen kann.
                            Aber, Du könntest es in getrennten Dateien ausgeben und dann im Batch die Datei zu einer zusammenfügen; dabei kannst Du die Reihenfolge angeben.

                            Dich stört doch in der Ausgabe der Hinweis auf den Kontext-Switch?
                            Dann probier mal folgendes:
                            (Use weglassen)

                            SELECT DISTINCT [" + merkmal + "] FROM " + datenbankname + ".." + tabellenname + ";"));

                            Man kann bei Statements den "voll-qualifizierten Namen" angeben, also

                            [Server\Instanz].[Datenbank].[Schema].[Tabelle/View/Objekt]

                            Deine Nachfrage zur Konvertierung verstehe ich nun wieder nicht so ganz.

                            Wenn Du Dir Daten aus einem Feld vom Typ DateTime zurückliefern lässt, bekommst Du es auch typsicher als DateTime; die Formatierung für die Anzeige nimmt man ja im Client vor.

                            Wenn Du auf ein Feld vom Typ DateTime filtern willst und den Wert zwangsweise als String übergibst, sollte man auch mit angeben, in welchem Format es vorliegt.
                            Wie sollte SQL auch sonst zwischen EN-GB und EN-US beim Datum unterscheiden?

                            Bei 20080512 brauchst Du nichts weiter angeben, das geht auch ohne Formatangabe:

                            select convert(smalldatetime, '20080512')
                            Olaf Helper

                            <Blog> <Xing>
                            * cogito ergo sum * errare humanum est * quote erat demonstrandum *
                            Wenn ich denke, ist das ein Fehler und das beweise ich täglich

                            Comment


                            • #15
                              danke für den tip bzgl. datenbankkontext wechsel.

                              zu den date-datentypen:

                              ich würde gerne eine spalte vom typ smalldatetime in eine spalte vom typ nvarchar(100) umwandeln, so dass das datum wie folgt formatiert ist:

                              JJJJ-MM-TT

                              zb. 2008-0821
                              oder meinetwegen auch mit doppelpunkten: 2008:08:21

                              lässt sich dies bewerkstelligen? wie?

                              Code:
                              --Datentyp der Spalte Datum auf nvarchar(100) setzten
                              ALTER TABLE tabelle
                                          ALTER COLUMN [Datum] [nvarchar](100)
                              GO
                              So kommt es leider in dem etwas unschönen format:

                              Apr 22 2008 12:00AM

                              Comment

                              Working...
                              X