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")