SQL Queries¶
The SQL API lets you query the game database directly from Lua scripts using ODBC connections.
Getting a Connection¶
Tip
Connections are cached per name. Calling GetConnection("GameDB") a second time returns the same instance — no need to reconnect.
Reading Player Data¶
local function GetPlayerResets(playerName)
local db = GetConnection("GameDB")
db:ExecQuery("SELECT Reset, MasterReset FROM Character WHERE Name = '" .. playerName .. "'")
if db:Fetch() then
local resets = db:GetAsInteger("Reset")
local masterResets = db:GetAsInteger("MasterReset")
db:Close()
return resets, masterResets
end
db:Close()
return 0, 0
end
-- Usage in a command handler
BridgeFunctionAttach("OnCommandManager", function(aIndex, code, arg)
if code == 200 then
local player = GetUser(aIndex)
if player == nil then return 0 end
local resets, mr = GetPlayerResets(player.Name)
GCNoticeSend(aIndex, 1, "Resets: " .. resets .. " | Master Resets: " .. mr)
return 1
end
return 0
end)
Online Player Ranking¶
local function ShowTopPlayers(aIndex)
local db = GetConnection("GameDB")
db:ExecQuery("SELECT TOP 5 Name, Reset, MasterReset FROM Character ORDER BY MasterReset DESC, Reset DESC")
GCNoticeSend(aIndex, 1, "--- Top 5 Players ---")
local rank = 1
while db:Fetch() do
local name = db:GetAsString("Name")
local resets = db:GetAsInteger("Reset")
local mr = db:GetAsInteger("MasterReset")
GCNoticeSend(aIndex, 1, "#" .. rank .. " " .. name .. " - MR:" .. mr .. " R:" .. resets)
rank = rank + 1
end
db:Close()
end
Writing Data¶
local function SaveCustomData(playerName, eventScore)
local db = GetConnection("GameDB")
local query = string.format(
"IF EXISTS (SELECT 1 FROM CustomEventScores WHERE Name = '%s') "..
"UPDATE CustomEventScores SET Score = %d WHERE Name = '%s' "..
"ELSE INSERT INTO CustomEventScores (Name, Score) VALUES ('%s', %d)",
playerName, eventScore, playerName, playerName, eventScore
)
db:ExecQuery(query)
db:Close()
end
SQL Injection
The examples above use string concatenation for simplicity. In production, use BindParameterAsString for user-provided input to prevent SQL injection.
Using Parameterized Queries¶
local function SafeGetPlayer(playerName)
local db = GetConnection("GameDB")
db:BindParameterAsString(1, playerName)
db:ExecQuery("SELECT Reset FROM Character WHERE Name = ?")
local resets = 0
if db:Fetch() then
resets = db:GetAsInteger("Reset")
end
db:Close()
return resets
end
QueryManager Methods Reference¶
| Method | Description |
|---|---|
Connect(dsn, user, pass) |
Open ODBC connection |
ExecQuery(sql) |
Execute SQL query |
Fetch() |
Get next result row (true/false) |
Close() |
Close current query |
GetAsInteger(col) |
Read integer column |
GetAsFloat(col) |
Read float column |
GetAsInteger64(col) |
Read 64-bit integer |
GetAsString(col) |
Read string column |
GetAsBinary(col) |
Read binary data |
BindParameterAsString(n, val) |
Bind string parameter |
BindParameterAsBinary(n, val) |
Bind binary parameter |