DB-Tool zur Erweiterten Abfrage der Spaltentypen [PB 4.40b7]

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
dag
Beiträge: 12
Registriert: 16.06.2009 15:01

DB-Tool zur Erweiterten Abfrage der Spaltentypen [PB 4.40b7]

Beitrag von dag »

.. Und wieder hatt ich ein Problem, und will euch die Lösung nicht vorenthalten:

Routine zum Feststellen der Spaltentypen in einer Tabelle
Grund wozu progged: DatabaseColumnType() gibt etliche Datentypen nicht zurück.
zB Binary, Money, Datetime, Timestamp usw.
Diese Routine holt die Typen aus den System-Definitionstabellen.
Es werden bisher 3 Datenbanken abgehandelt:

Microsoft SQL Server (ODBC)
MySQL (ODBC)
SQLite

weitere Folgen.
Thomas

Code: Alles auswählen

;
; Free Code
; Purebasic v4.40b7
; 25.11.2009
; Thomas


Procedure.s DB_ColumnTyp(db_hnd,dbtyp$,spaltname$,table$)
  showcol$=""
  dbtyp$ = UCase(dbtyp$)            ; Einheitlich Grossschrift
  If FindString(dbtyp$,"MYSQL",1) > 0
      showcol$="SHOW COLUMNS FROM "+table$+";"    ; Mysql Systabelle abfragen
      dt = 0  ; Flag für dbtyp
  ElseIf FindString(dbtyp$,"SQL SERVER",1) > 0
      showcol$="Select * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '"+table$+"'" ; M$ sqlserver Systabelle abfragen
      dt = 1
  ElseIf FindString(dbtyp$,"SQLITE",1) >0
      showcol$ ="Select sql FROM sqlite_master WHERE name = '"+table$+"';"    ; SQLite Systabelle abfragen
      dt = 2
  EndIf
  check = DatabaseQuery(db_hnd,showcol$)
  If check = 0: MessageRequester("DB Fehler","Felderabfrage misslungen: "+DatabaseError()) : EndIf
  If FirstDatabaseRow(db_hnd) > 0       ; WEnn SYSTabelle  im zugriff ist, dann mach
    rueck$ = ""
    Repeat
      If dt = 0   ; MySQL
          name$ = GetDatabaseString(db_hnd,0) ; Spalte 0 - Name
          ttmp$ = GetDatabaseString(db_hnd,1) ; Spalte 1 - Typ
          t1$   = StringField(ttmp$,1,"(")  ; typ
          If name$ = spaltname$             ; Ist es die gesuchte Spalte
            rueck$ = t1$                    ; ..dann rückgabe des Typs
            Break 
          EndIf
      ElseIf dt = 1  ; MSSql
        name$ = GetDatabaseString(db_hnd,3)  ; Spalte 3 (Name)  
        type$ = GetDatabaseString(db_hnd,7)  ; Spalte 7 (Typ)
        If name$ = spaltname$  ; gefunden ?
          rueck$ = type$       ; dann rückgabe des Typs
          Break
        EndIf
      ElseIf dt = 2 ; SQLite 
        erg$   = GetDatabaseString(db_hnd,0) ; Alles in Spalte 0 als Zeichenkette
        anzahl = CountString(erg$,",")+1    ; In dieser Kette sind alle definitionen , so wie bei Create eingegeben
                                    ; Debug erg$    ; Uncomment um sich das anzusehen
        For i=1 To anzahl
          a$ = Trim(StringField(erg$,i,","))    ; Einfache Stringverarbeitung über alle Spalten (sind ja mit "," getrennt
          If FindString(a$,"`",0)
            trenn1$ = "`"
            trenn2$ = "`"
          Else
            trenn1$ = "["
            trenn2$ = "]"
          EndIf
          If i=1 : t$ = Trim(StringField(a$,2,"(")) : Else : t$ = a$ :EndIf
          If t$="":Continue : EndIf  ; Leer? dann next
          b$  = StringField(t$,2,trenn1$)
          tx$ = StringField(b$,1,trenn2$) ;ok [
          If trenn1$ = "[" 
            If i=1
              typ$ = Trim(StringField(t$,2,trenn2$)) ; ok [
            Else
              tmp$ = StringField(b$,2,trenn2$)
              typ$ = Trim(StringField(tmp$,1,"("))
            EndIf
          ElseIf trenn1$ = "`"
            tmp$ = StringField(t$,3,trenn1$)
            typ$ = Trim(StringField(tmp$,1,"("))
          EndIf
          If i =1: c$ = Trim(StringField(a$,3,"(")) : Else : c$= Trim(StringField(t$,2,"(")) : EndIf
          feldlaenge$ = StringField(c$,1,")")
          If tx$ = spaltname$       ; Namen gefunden ?
            rueck$ = typ$           ; Dann Typrückgabe und raus ( Break)
            Break
          EndIf
        Next i
      EndIf
    Until NextDatabaseRow(db_hnd)=0 Or rueck$ >""
    ProcedureReturn rueck$
  EndIf
EndProcedure

; Anwendungsbeispiel mit SQLite
UseSQLiteDatabase()

; Create DB
tmpf = OpenFile(#PB_Any,GetHomeDirectory()+"test.sql")
If IsFile(tmpf) : CloseFile(tmpf) : EndIf
db_hnd = OpenDatabase(#PB_Any,GetHomeDirectory()+"test.sql","","",#PB_Database_SQLite)
If db_hnd = 0: MessageRequester("OPEN-Error","Error : "+DatabaseError()) : End :EndIf

; Create Tabellen
tabl$ = "CREATE TABLE IF NOT EXISTS `typtest` (`Indexfeld` INTEGER(5) Not NULL ON CONFLICT IGNORE, `datum` DATETIME(14), `binfeld` BINARY(50), `Geld` MONEY(11));"
check = DatabaseUpdate(db_hnd,tabl$)
If check = 0 : MessageRequester("Error update"," Error : "+DatabaseError()) : End:EndIf

; Feldtypausgabe:
Debug "indexfeld: " + DB_ColumnTyp(db_hnd,"SQLite","Indexfeld","typtest")
Debug "datum: " + DB_ColumnTyp(db_hnd,"SQLite","datum","typtest")
Debug "binfeld: " + DB_ColumnTyp(db_hnd,"SQLite","binfeld","typtest")
Debug "geld : " + DB_ColumnTyp(db_hnd,"SQLite","Geld","typtest")
Bild