RosettaCodeData/Task/Parameterized-SQL-statement/Pascal/parameterized-sql-statement...

125 lines
4.1 KiB
ObjectPascal

program Parametrized_SQL_Statement;
uses
sqlite3, sysutils;
const
DB_FILE : PChar = ':memory:'; // Create an in-memory database.
var
DB :Psqlite3;
ResultCode :Integer;
SQL :PChar;
InsertStatements :array [1..4] of PChar;
CompiledStatement :Psqlite3_stmt;
i :integer;
{ CheckError
Checks the result code from an SQLite operation.
If it contains an error code then this procedure prints the error message,
closes the database and halts the program. }
procedure CheckError(ResultCode: integer; DB: Psqlite3);
begin
if ResultCode <> SQLITE_OK then
begin
writeln(format('Error #%d: %s', [ResultCode, sqlite3_errmsg(db)]));
sqlite3_close(DB);
halt(ResultCode);
end;
end;
{ SelectCallback
This callback function prints the results of the select statement.}
function SelectCallback(Data: pointer; ColumnCount: longint; Columns: PPChar; ColumnNames: PPChar):longint; cdecl;
var
i :longint;
col :PPChar;
begin
col := Columns;
for i:=0 to ColumnCount-1 do
begin
write(col^); // Print the current column value.
inc(col); // Advance the pointer.
if i<>ColumnCount-1 then write(' | ');
end;
writeln;
end;
begin
// Open the database.
ResultCode := sqlite3_open(DB_FILE, @DB);
CheckError(ResultCode, DB);
// Create the players table in the database.
SQL := 'create table players(' +
'id integer primary key asc, ' +
'name text, ' +
'score real, ' +
'active integer, ' + // Store the bool value as integer (see https://sqlite.org/datatype3.html chapter 2.1).
'jerseyNum integer);';
ResultCode := sqlite3_exec(DB, SQL, nil, nil, nil);
CheckError(ResultCode, DB);
// Insert some values into the players table.
InsertStatements[1] := 'insert into players (name, score, active, jerseyNum) ' +
'values (''Roethlisberger, Ben'', 94.1, 1, 7);';
InsertStatements[2] := 'insert into players (name, score, active, jerseyNum) ' +
'values (''Smith, Alex'', 85.3, 1, 11);';
InsertStatements[3] := 'insert into players (name, score, active, jerseyNum) ' +
'values (''Manning, Payton'', 96.5, 0, 18);';
InsertStatements[4] := 'insert into players (name, score, active, jerseyNum) ' +
'values (''Doe, John'', 15, 0, 99);';
for i:=1 to 4 do
begin
ResultCode := sqlite3_exec(DB, InsertStatements[i], nil, nil, nil);
CheckError(ResultCode, DB);
end;
// Display the contents of the players table.
writeln('Before update:');
SQL := 'select * from players;';
ResultCode := sqlite3_exec(DB, SQL, @SelectCallback, nil, nil);
CheckError(ResultCode, DB);
// Prepare the parametrized SQL statement to update player #99.
SQL := 'update players set name=?, score=?, active=? where jerseyNum=?;';
ResultCode := sqlite3_prepare_v2(DB, SQL, -1, @CompiledStatement, nil);
CheckError(ResultCode, DB);
// Bind the values to the parameters (see https://sqlite.org/c3ref/bind_blob.html).
ResultCode := sqlite3_bind_text(CompiledStatement, 1, PChar('Smith, Steve'), -1, nil);
CheckError(ResultCode, DB);
ResultCode := sqlite3_bind_double(CompiledStatement, 2, 42);
CheckError(ResultCode, DB);
ResultCode := sqlite3_bind_int(CompiledStatement, 3, 1);
CheckError(ResultCode, DB);
ResultCode := sqlite3_bind_int(CompiledStatement, 4, 99);
CheckError(ResultCode, DB);
// Evaluate the prepared SQL statement.
ResultCode := sqlite3_step(CompiledStatement);
if ResultCode <> SQLITE_DONE then
begin
writeln(format('Error #%d: %s', [ResultCode, sqlite3_errmsg(db)]));
sqlite3_close(DB);
halt(ResultCode);
end;
// Destroy the prepared statement object.
ResultCode := sqlite3_finalize(CompiledStatement);
CheckError(ResultCode, DB);
// Display the contents of the players table.
writeln('After update:');
SQL := 'select * from players;';
ResultCode := sqlite3_exec(DB, SQL, @SelectCallback, nil, nil);
CheckError(ResultCode, DB);
// Close the database connection.
sqlite3_close(db);
end.