String als Bindungsvariable mit SetDatabaseString

Anfängerfragen zum Programmieren mit PureBasic.
Istvan42
Beiträge: 16
Registriert: 15.12.2019 16:59
Computerausstattung: MacOS Sonoma (M1), PureBasic 6.03 LTS (MacOS X - x64)

String als Bindungsvariable mit SetDatabaseString

Beitrag von Istvan42 »

Hallo zusammen,

für eine SQLite DB würde ich gerne einen String als Bindungsvariable mit SetDatabaseString(#Datenbank, StatementIndex, Wert$) festlegen. Bekomme es aber nicht hin und finde den Fehler nicht.

Folgendes funktioniert (ohne String als Bindungsvariable):

Code: Alles auswählen

sql = "ALTER TABLE " + table.s + " ADD " + column.s + " " + type.s + " ;"
If DatabaseUpdate(id, sql) <= 0
    Debug "Error in AddColumn Datenbankfehler " + DatabaseError()
EndIf
Folgendes haut nicht hin:

Code: Alles auswählen

sql.s = "ALTER TABLE ? ADD ? ?;"
  
  SetDatabaseString(id, 0, table.s)
  SetDatabaseString(id, 1, column.s)
  SetDatabaseString(id, 2, type.s)
  
If DatabaseUpdate(id, sql.s) <= 0
    Debug "Error in AddColumn Datenbankfehler " + DatabaseError()
EndIf
Der DatabaseError() meldet einen Syntax-Fehler in der Nähe von "?"

Ich stehe auf dem Schlauch. Hat jemand eine Idee?

Grüße
Istvan42
MacOS Sonoma (M1), PureBasic 6.03 LTS (MacOS X - x64)
Andesdaf
Moderator
Beiträge: 2658
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: String als Bindungsvariable mit SetDatabaseString

Beitrag von Andesdaf »

Was steht denn so in table.s, type.s und column.s?
Win11 x64 | PB 6.00 (x64)
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: String als Bindungsvariable mit SetDatabaseString

Beitrag von ccode_new »

@Andesdaf:
Es ist erstmal nicht die Tatsache was in table.s, type.s, oder columns.s steht.

Auch wenn da bisher noch nichts selber eingetragen wurde, es sind trotzdem legitime Zeichenketten.

Und was Istvan42 hier macht:
sql.s = "ALTER TABLE ? ADD ? ?;"

SetDatabaseString(id, 0, table.s)
SetDatabaseString(id, 1, column.s)
SetDatabaseString(id, 2, type.s)

If DatabaseUpdate(id, sql.s) <= 0
Debug "Error in AddColumn Datenbankfehler " + DatabaseError()
EndIf
ist doch laut PureBasic-Hilfe vollkommen in Ordnung.

Es geht hierbei um die Tatsache, dass man es einfach nicht so schreiben kann.

Wenn man es so schreibt:

table.s = "food"
column.s = "cookies"
type.s = "CHAR(50)"
sql = "ALTER TABLE " + table + " ADD " + column + " " + type + " ;"

liefert die Funktion: DatabaseUpdate() eine 1

Bei der anderen Variante aber eine 0.

@Istvan42

Die "SetDatabase" Befehle sind eigentlich nur für das Setzen von Werten innerhalb der Datenbank. (Datenbankfelder)

Bei einer normalen Datenbankanweisung musst du eine ganz normale Zeichenkette aus deinen normalen Zeichenketten-Variablen bauen.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: String als Bindungsvariable mit SetDatabaseString

Beitrag von #NULL »

- der erste Query hat ein Space vor dem Semikolon, der zweite nicht.
- Rückgabewert von DatabaseUpdate() ist bei Fehler 0 und nicht <= 0.
- column vs columns.

Leider bekomme ich den Syntax Error trotzdem.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: String als Bindungsvariable mit SetDatabaseString

Beitrag von #NULL »

ccode_new hat geschrieben:Die "SetDatabase" Befehle sind eigentlich nur für das Setzen von Werten innerhalb der Datenbank. (Datenbankfelder)

Bei einer normalen Datenbankanweisung musst du eine ganz normale Zeichenkette aus deinen normalen Zeichenketten-Variablen bauen.
Ich glaube da hast du recht:
Generally one cannot use SQL parameters/placeholders for database identifiers (tables, columns, views, schemas, etc.) or database functions (e.g., CURRENT_DATE), but instead only for binding literal values.
SQLite Parameters - Not allowing tablename as parameter
my pb stuff..
Bild..jedenfalls war das mal so.
Andesdaf
Moderator
Beiträge: 2658
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: String als Bindungsvariable mit SetDatabaseString

Beitrag von Andesdaf »

ccode_new hat geschrieben: Es ist erstmal nicht die Tatsache was in table.s, type.s, oder columns.s steht.

Auch wenn da bisher noch nichts selber eingetragen wurde, es sind trotzdem legitime Zeichenketten.
Ich hatte so einen Fall schon mal vor Jahren, da verhielt sich die Behandlung mit gebundenen Parametern
anders. Ich weiß aber nicht mehr genau, unter welchen Voraussetzungen; hier hast du aber natürlich Recht.
Bindung nur mit "echten" Werten.
Win11 x64 | PB 6.00 (x64)
Istvan42
Beiträge: 16
Registriert: 15.12.2019 16:59
Computerausstattung: MacOS Sonoma (M1), PureBasic 6.03 LTS (MacOS X - x64)

Re: String als Bindungsvariable mit SetDatabaseString

Beitrag von Istvan42 »

Hallo zusammen,

wie hier auch schon vermutet wurde, habe ich die Funktion nicht so verwendet, wie es sein soll. Ich reime mir das jetzt so zusammen:

Da die eingegebenen Daten nun als Parameter an die Query übergeben werden, kann kein Teil davon als zusätzliche SQL-Anweisung behandelt werden. Es ist nur eine Übergabe an ein Datenfeld erlaubt und jede "Injektion" ist ungültig. Der Sinn der Verwendung von Variablen-Bindung besteht ja gerade darin SQL-Injection-Angriffe zu vermeiden.

Es können nur Daten, die in einem Datenfeld in der Tabelle einer Datenbank gespeichert werden, mit den Methoden verwendet werden. Nicht aber Ausdrücke, die zum SQL-Befehl gehören. Ein Tabellenname ist beispielsweise kein Datum, der in einem Datenfeld einer Tabelle gespeichert werden soll und kann daher nicht verwendet werden.

Leider gibt der Compiler oder der Debugger keine Fehlermeldung aus, wenn versucht wird, einen Parameter eines SQL-Befehlts statt den Wert eines Datenfeldes mit der SQLite Variabel Bindung zu verwenden.

Erst mit dem Aufruf von DatabaseError() kann man einen Hinweis auf ein Problem erhalten.

Bsp.:

Error in NewTable. Datenbankfehler near "?": syntax error ist aufgetreten.

Ein entsprechender Hinweis mit einem Beispiel in der Doku wäre sicherlich hilfreich, da ich mit meiner Frage nicht alleine bin.

Damit sollte die Ursache für mein Problem geklärt sein, oder gibt es noch Anmerkungen?

Gruß
Istvan42
Antworten