• Offizieller Beitrag

    Hi,
    da SQLite seine Stärken dann ausspielen kann, wenn viele Operationen auf einen Schlag abgearbeitet werden sollen, ist es wenig sinnvoll jeden INSERT- oder UPDATE-Vorgang separat zu coden.
    Mit den UDF _SQLite_INSERT() und _SQLite_UPDATE() besteht die Möglichkeit weitestgehend ohne SQL-Syntax zu arbeiten (außer WHERE-Klausel bei UPDATE).
    Die Daten können als String (Einzeloperation) oder als Array übergeben werden.
    Ich denke, das spart eine ganze Menge Schreibarbeit. ;)

    Edit 11.05.2014
    Ich habe mal wieder etwas mit SQLite gearbeitet und dabei sind einige neue Dinge angefallen ;)
    - INSERT kpl. neu
    - weitere Funktionen hinzugefügt

    Funktionen
    SQLiteMore.au3 (v0.2)
    [autoit]


    ;===================================================================================================
    ; Function Name....: _SQLite_TableExists
    ; Description......: Prüft eine Tabelle auf Existenz
    ; Parameter(s).....: $_sTable Tabellenname
    ; Requirement(s)...: Eine mit _SQLite_Open() geöffnete DB
    ; .................: #include <SQLite.au3>
    ; Return Value(s)..: Erfolg: True / False
    ; .................: Fehler: False, @error = 1, @extended = SQLite-@error
    ; Author(s)........: BugFix ([email='bugfix@autoit.de'][/email])
    ;===================================================================================================
    Func _SQLite_TableExists($_sTable)
    Local $hQuery, $aQuery, $fRet = False, $sErr
    If $SQLITE_OK <> _SQLite_Query(-1, "SELECT name FROM sqlite_master WHERE type='table'", $hQuery) Then
    $sErr = _SQLite_ErrCode()
    _SQLite_QueryFinalize($hQuery)
    Return SetError(1,$sErr,False)
    EndIf
    While _SQLite_FetchData($hQuery, $aQuery) = $SQLITE_OK
    If $aQuery[0] = $_sTable Then
    $fRet = True
    ExitLoop
    EndIf
    WEnd
    _SQLite_QueryFinalize($hQuery)
    Return $fRet
    EndFunc ;==>_SQLite_TableExists

    [/autoit] [autoit][/autoit] [autoit]

    ;===================================================================================================
    ; Function Name....: _SQLite_SelectAll
    ; Description......: Wählt alle Felder einer Tabelle für eine gegebene Bedingung aus
    ; Parameter(s).....: $_sTable Tabellenname
    ; .................: $_sWhere WHERE - Bedingung ohne Schlüsselwort (Standard='', gibt gesamte Tabelle aus)
    ; Requirement(s)...: Eine mit _SQLite_Open() geöffnete DB
    ; .................: #include <SQLite.au3>
    ; Return Value(s)..: Erfolg: Ergebnisarray
    ; .................: Fehler: 1, @error = 1, @extended = SQLite-@error
    ; Author(s)........: BugFix ([email='bugfix@autoit.de'][/email])
    ;===================================================================================================
    Func _SQLite_SelectAll($_sTable, $_sWhere='')
    If $_sWhere <> '' Then $_sWhere = " WHERE " & StringRegExpReplace($_sWhere, '([^;]+)([;]*)$', '$1;')
    Local $aResult, $iRows, $iColumns
    If $SQLITE_OK <> _SQLite_GetTable2d(-1, "SELECT * FROM " & $_sTable & $_sWhere, $aResult, $iRows, $iColumns) Then
    Return SetError(1,_SQLite_ErrCode(),1)
    Else
    Return $aResult
    EndIf
    EndFunc ;==>_SQLite_SelectAll

    [/autoit] [autoit][/autoit] [autoit]

    ;===================================================================================================
    ; Function Name....: _SQLite_CountRows
    ; Description......: Ermittelt die Anzahl von Datensätzen für eine Tabelle
    ; Parameter(s).....: $_sTable Tabellenname
    ; Requirement(s)...: Eine mit _SQLite_Open() geöffnete DB
    ; .................: #include <SQLite.au3>
    ; Return Value(s)..: Erfolg: Anzahl der Datensätze
    ; .................: Fehler: -1 @error = 1, @extended = SQLite-@error
    ; Author(s)........: BugFix ([email='bugfix@autoit.de'][/email])
    ;===================================================================================================
    Func _SQLite_CountRows($_sTable)
    Local $hQuery, $aQuery, $iRet = 0, $iErr
    If $SQLITE_OK <>_SQLite_Query(-1, "SELECT count(*) FROM " & $_sTable & ";", $hQuery) Then
    $iErr = _SQLite_ErrCode()
    _SQLite_QueryFinalize($hQuery)
    Return SetError(1,$iErr,-1)
    EndIf
    While _SQLite_FetchData($hQuery, $aQuery) = $SQLITE_OK
    $iRet = $aQuery[0]
    WEnd
    _SQLite_QueryFinalize($hQuery)
    Return $iRet
    EndFunc ;==>_SQLite_CountRows

    [/autoit] [autoit][/autoit] [autoit]

    ;===================================================================================================
    ; Function Name....: _SQLite_ColumnsInfo
    ; Description......: Ermittelt die Anzahl von Spalten für eine Tabelle, optional auch Namen oder Typen der Spalten
    ; Parameter(s).....: $_sTable Tabellenname
    ; ....optional.....: $_iNames 0 (Standard) - nur Anzahl
    ; .................: 1 - gibt Array mit Spaltennamen und Anzahl an Index 0 zurück.
    ; .................: 2 - gibt Array mit Spaltentypen und Anzahl an Index 0 zurück.
    ; Requirement(s)...: Eine mit _SQLite_Open() geöffnete DB
    ; .................: #include <SQLite.au3>
    ; Return Value(s)..: Erfolg: Anzahl der Spalten oder Array mit Anzahl und allen Spaltennamen/-Typen
    ; .................: Fehler: -1 @error = 1, @extended = SQLite-@error
    ; Author(s)........: BugFix ([email='bugfix@autoit.de'][/email])
    ;===================================================================================================
    Func _SQLite_ColumnsInfo($_sTable, $_iNames=0)
    Local $hQuery, $aQuery, $cid, $sCol = '', $sTypes = '', $iErr
    If $SQLITE_OK <> _SQLite_Query(-1, "PRAGMA table_info(" & $_sTable & ");", $hQuery) Then
    $iErr = _SQLite_ErrCode()
    _SQLite_QueryFinalize($hQuery)
    Return SetError(1,$iErr,-1)
    EndIf
    While _SQLite_FetchData($hQuery, $aQuery) = $SQLITE_OK
    $cid = $aQuery[0]
    If $sCol <> '' Then $sCol &= ','
    If $sTypes <> '' Then $sTypes &= ','
    $sCol &= $aQuery[1]
    $sTypes &= $aQuery[2]
    WEnd
    _SQLite_QueryFinalize($hQuery)
    Switch $_iNames
    Case 0
    Return $cid +1
    Case 1
    Return StringSplit($sCol, ',')
    Case 2
    Return StringSplit($sTypes, ',')
    EndSwitch
    EndFunc ;==>_SQLite_ColumnsInfo

    [/autoit] [autoit][/autoit] [autoit]

    ;===================================================================================================
    ; Function Name....: _SQLite_INSERT
    ; Description......: Fügt Daten aus einem String/1D-Array/2D-Array in eine Tabelle ein. Leere Inhalte werden automatisch mit "NULL" besetzt
    ; Parameter(s).....: $_sTable Tabellenname
    ; .................: $_vValues String/Array mit Werten
    ; ....optional.....: $_iIndexStart Array-Index ab dem Werte übernommen werden. (Standard=0)
    ; ....optional.....: $_sDelim Trennzeichen, wenn $_vValues ein String ist. (Standard=',')
    ; Requirement(s)...: Eine mit _SQLite_Open() geöffnete DB
    ; .................: #include <SQLite.au3>
    ; .................: _SQLite_ColumnsInfo()
    ; Return Value(s)..: Erfolg: $SQLITE_OK
    ; .................: Fehler: 1 @error = 1 übergebene Spaltenzahl falsch
    ; .................: @error = 2 Insert fehlgeschlagen @extended = Insert-@error
    ; Author(s)........: BugFix ([email='bugfix@autoit.de'][/email])
    ;===================================================================================================
    Func _SQLite_INSERT($_sTable, $_vValues, $_iIndexStart=0, $_sDelim=',')
    If Not IsArray($_vValues) Then $_vValues = StringSplit($_vValues, $_sDelim, 3)
    Local $aValues[1][UBound($_vValues-$_iIndexStart)]
    If UBound($_vValues,0) = 1 Then
    For $i = $_iIndexStart To UBound($_vValues) -1
    $aValues[0][$i] = $_vValues[$i]
    Next
    Else
    $aValues = $_vValues
    EndIf
    Local $sSQL = 'BEGIN TRANSACTION;', $sEdge, $iColTable = -1
    Local $iColArray = UBound($aValues,2), $sValue
    Local $aTypes = _SQLite_ColumnsInfo($_sTable, 2)
    If IsArray($aTypes) Then $iColTable = $aTypes[0]
    If $iColTable = -1 Or ($iColTable <> $iColArray) Then Return SetError(1,0,1)
    For $i = $_iIndexStart To UBound($aValues) -1
    $sSQL &= 'INSERT INTO ' & $_sTable & ' VALUES ('
    For $j = 0 To $iColArray -1
    $sValue = $aValues[$i][$j]
    If $sValue = '' Then
    $sValue = 'NULL'
    Else
    $sEdge = '"'
    If $aTypes[$j+1] <> 'TEXT' Then $sEdge = ''
    $sValue = $sEdge & $sValue & $sEdge
    EndIf
    $sSQL &= $sValue & ','
    Next
    $sSQL = StringTrimRight($sSQL, 1) & ');'
    Next
    $sSQL &= 'END TRANSACTION;'
    If $SQLITE_OK <> _SQLite_Exec(-1, $sSQL) Then
    Return SetError(2,_SQLite_ErrCode(),1)
    Else
    Return $SQLITE_OK
    EndIf
    EndFunc ;==>_SQLite_INSERT

    [/autoit] [autoit][/autoit] [autoit]

    ;===================================================================================================
    ; Function Name: _SQLite_UPDATE($sTable, $saField_Value, $sWhere=-1, $Delim=',')
    ; Description:: Updatet Werte in eine existierende Tabelle einer geöffneten SQLite
    ; DB
    ; Parameter(s): $sTable String des Tabellennamens
    ; $saFieldValue String ODER 1D-Array mit den Feld-Wert Paaren
    ; $sWhere Bedingung für das SQL-Statement, Standard -1
    ; gültig für alle DS
    ; $Delim Trennzeichen zwischen Feld und Wert, Standard:','
    ; Requirement(s): Eine mit _SQLite_Open() geöffnete DB
    ; #include <SQLite.au3>
    ; Return Value(s): Erfolg $SQLITE_OK
    ; Fehler 1 @error = 1, Update fehlgeschlagen
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===================================================================================================
    Func _SQLite_UPDATE($sTable, $saField_Value, $sWhere=-1, $Delim=',')
    Local $sUpdate = "UPDATE " & $sTable & " SET "
    If Not IsArray($saField_Value) Then
    Local $aValues[1] = [$saField_Value]
    Else
    Local $aValues = $saField_Value
    EndIf
    For $i = 0 To UBound($aValues) -1
    Local $splitVal = StringSplit($aValues[$i], $Delim)
    $sUpdate &= StringStripWS($splitVal[1], 3) & " = '" & StringStripWS($splitVal[2], 3) & "',"
    Next
    $sUpdate = StringTrimRight($sUpdate, 1)
    If $sWhere <> -1 Then $sUpdate &= " WHERE " & $sWhere
    If $SQLITE_OK <> _SQLite_Exec ( -1, $sUpdate ) Then
    Return SetError(1,0,1)
    Else
    Return $SQLITE_OK
    EndIf
    EndFunc ;==>_SQLite_UPDATE

    [/autoit]
    Beispielskript
    [autoit]


    #include <SQLite.au3>
    _SQLite_Startup(@ScriptDir & "\sqlite3.dll", False, 1) ; == SQLite.dll liegt im @ScriptDir
    _SQLite_Open(@ScriptDir & '\test.db')

    [/autoit] [autoit][/autoit] [autoit]

    $sSQL = _
    "CREATE TABLE IF NOT EXISTS [test_tab] (" & _
    "[kdnr] INTEGER PRIMARY KEY AUTOINCREMENT," & _
    "[titel] TEXT," & _
    "[firma] TEXT," & _
    "[name] TEXT NOT NULL," & _
    "[vorname] TEXT," & _
    "[strasse] TEXT," & _
    "[nr] TEXT," & _
    "[plz] TEXT," & _
    "[ort] TEXT," & _
    "[telefon] TEXT," & _
    "[gebdat] TEXT);" & _
    "INSERT INTO sqlite_sequence VALUES ('test_tab', 9999);" ; == Vorbelegung KD-Nr Startwert, gewünscht: 10000 (9999 +1 autoincrement = 10000)

    [/autoit] [autoit][/autoit] [autoit]

    ; == Tabelle erstellen, wenn nicht vorhanden und Startwert setzen für AutoIncrement-Wert
    If Not _SQLite_TableExists('test_tab') Then
    _SQLite_Exec(-1, $sSQL)
    ConsoleWrite('Tabelle erstellt' & @LF)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; == INSERT einzelner DS als String
    $sInsert = ",Dr.,Musterbau AG,Schmidt,Holger,Hauptstrasse,21,06218,Halle,,"

    [/autoit] [autoit][/autoit] [autoit]

    If $SQLITE_OK <> _SQLite_INSERT('test_tab', $sInsert) Then
    MsgBox(0, 'Fehler INSERT', 'Fehler-Nr.: ' & _SQLite_ErrCode() & @CRLF & @CRLF & 'Fehler-Text: ' & _SQLite_ErrMsg())
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; == INSERT einzelner DS als 1D-Array
    Global $aInsert1D[11] = ['','','Hanswurst GmbH','Wurst','Hans','Ledergasse','15','12345','Bratenau','01122-334455','']

    [/autoit] [autoit][/autoit] [autoit]

    If $SQLITE_OK <> _SQLite_INSERT('test_tab', $aInsert1D) Then
    MsgBox(0, 'Fehler INSERT', 'Fehler-Nr.: ' & _SQLite_ErrCode() & @CRLF & @CRLF & 'Fehler-Text: ' & _SQLite_ErrMsg())
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; == INSERT mehrere DS als 2D-Array
    Global $aInsert[8][11] = [ _
    ['','','Spökenkieker KG','Schluck','Hein','An der Twiete','1a','21023','Hamburg','040-646589',''], _
    ['','','Ich & Du GmbH','Meyer','Peter und Paul','Randstrasse','114','45678','Amsee','',''], _
    ['','','Tischlerei Buchenhorst','Buchenhorst','Klaus-Peter','Am Wald','36','87663','Waldershausen','',''], _
    ['','','Glaserei Bruch','Bruch','Reiner','Industriegasse','17','39864','Dorf in der Altmark','',''], _
    ['','','KFZ-Reparatur Stotter','Stotter','Ingolf','Amselgrund','8','76542','Schönhausen','',''], _
    ['','','Blumen & Mehr','Rose','Claudia','Kirschgarten','36','15446','Bei Berlin','010-152637',''], _
    ['','','Einzelhandel Ton, Steine, Scherben','Krug','Minna','Krügergasse','78','64459','Neudorf','',''], _
    ['','','Diätwaren','Tella','Nu','Am Süßen See','10','06224','Halle','','']]

    [/autoit] [autoit][/autoit] [autoit]

    If $SQLITE_OK <> _SQLite_INSERT('test_tab', $aInsert) Then
    MsgBox(0, 'Fehler INSERT', 'Fehler-Nr.: ' & _SQLite_ErrCode() & @CRLF & @CRLF & 'Fehler-Text: ' & _SQLite_ErrMsg())
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; == die gesamte Tabelle mit _SQLite_SelectAll ausgeben
    $a = _SQLite_SelectAll('test_tab')
    _ArrayDisplay($a, 'alle Datensätze')

    [/autoit] [autoit][/autoit] [autoit]

    ; == alle Felder für die DS mit der gegebenen Bedingung ausgeben
    $a = _SQLite_SelectAll('test_tab', 'ort="Halle"')
    _ArrayDisplay($a, 'Datensätze mit Bedingung')

    [/autoit] [autoit][/autoit] [autoit]

    ; == Anzahl DS
    $DS = _SQLite_CountRows('test_tab')
    ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & " var: $DS --> " & $DS & @LF)

    [/autoit] [autoit][/autoit] [autoit]

    ; == Anzahl Spalten
    $Spaltenzahl = _SQLite_ColumnsInfo('test_tab')
    ConsoleWrite("@@ Debug line" & @TAB & @ScriptLineNumber & " var: $Spaltenzahl --> " & $Spaltenzahl & @LF)

    [/autoit] [autoit][/autoit] [autoit]

    ; == Feldnamen
    $a = _SQLite_ColumnsInfo('test_tab', 1)
    _ArrayDisplay($a, 'Feldnamen')

    [/autoit] [autoit][/autoit] [autoit]

    ; == Feldtypen
    $a = _SQLite_ColumnsInfo('test_tab', 2)
    _ArrayDisplay($a, 'Feldtypen')

    [/autoit]

    DL bisher: 399

  • Hi Bugfix. warum eigentlich dann kein _SQLite_DELETE() ? Oder ein SQLite_SELECT()?

    ---
    In "Independence Day" konnten die Windows-Erdcomputer problemlos mit denen der Außerirdischen kommunizieren. Was sagt uns das über unseren lieben Bill Gates? :D
    ---

  • Hallo BugFix,
    für die _SQLite_EXEC brauchst Du eigentlich keine @error-Abfrage.
    Die steht doch schon in der Funktion _SQLITE_EXEC selbst drin, oder?

    Spoiler anzeigen

    If @error > 0 Then
    Return SetError(1, 0, $SQLITE_MISUSE) ; DllCall Error
    EndIf

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

    • Offizieller Beitrag

    Hallo BugFix,
    für die _SQLite_EXEC brauchst Du eigentlich keine @error-Abfrage.
    Die steht doch schon in der Funktion _SQLITE_EXEC selbst drin, oder?


    Ja, du hast recht. Ich könnte statt 'If $SQLITE_OK <> _SQLite_Exec...' direkt 'Return _SQLite_Exec...' verwenden.
    Da meist mehr als eine Fehlerabfrage in Funktionen stattfindet, habe ich mir angewöhnt Fehler+Fehlernummer zurückzugeben. Ist in diesem Fall tatsächlich nicht notwendig, da nur ein einziger Fehlerfall auftreten kann.
    Danke für's aufmerksame Lesen. :rolleyes:

  • Ich habs aber schon gehabt, dass @error dann nicht weitergegeben wurde.
    Also braucht man 2 Zeilen:

    [autoit]

    Local $Return = _Func()
    Return SetError(@error,@extended,$Return)

    [/autoit]
  • Hallo zusammen,

    Ich habe eine Tabelle mit einem Primärschlüssel, welcher automatische hochgezählt wird. Ich weis jetzt leider nicht wie _SQLite_INSERT" befüllen muss, damit der Primärschlüssel korrekt hochgezählt wird.

    Aktuell bekomme ich einen SQL Fehler wenn ich folgendes versuche:

    [autoit]

    _SQLite_INSERT("MA", "Null,"&$a_Item[1]&","&$a_Item[2])

    [/autoit]


    --> Function: _SQLite_Exec
    --> Query: INSERT INTO MA VALUES ('Null','test','test1');
    --> Error: datatype mismatch

    ps: ich bin ein absoluter SQL anfänger :)
    vielen Dank für eure Hilfe.