Truy vấn SQL¶
API SQL cho phép bạn truy vấn cơ sở dữ liệu trò chơi trực tiếp từ kịch bản Lua sử dụng kết nối ODBC.
Lấy kết nối¶
Tip
Các kết nối được lưu bộ nhớ đệm theo tên. Gọi GetConnection("GameDB") lần thứ hai sẽ trả về cùng một instance — không cần kết nối lại.
Đọc dữ liệu người chơi¶
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
-- Sử dụng trong bộ xử lý lệnh
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)
Bảng xếp hạng người chơi trực tuyến¶
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
Ghi dữ liệu¶
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
Các ví dụ trên sử dụng nối chuỗi cho đơn giản. Trong môi trường thực tế, hãy sử dụng BindParameterAsString cho dữ liệu đầu vào từ người dùng để ngăn chặn SQL injection.
Sử dụng truy vấn có tham số¶
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
Tham khảo các phương thức QueryManager¶
| Phương thức | Mô tả |
|---|---|
Connect(dsn, user, pass) |
Mở kết nối ODBC |
ExecQuery(sql) |
Thực thi truy vấn SQL |
Fetch() |
Lấy hàng kết quả tiếp theo (true/false) |
Close() |
Đóng truy vấn hiện tại |
GetAsInteger(col) |
Đọc cột số nguyên |
GetAsFloat(col) |
Đọc cột số thực |
GetAsInteger64(col) |
Đọc số nguyên 64-bit |
GetAsString(col) |
Đọc cột chuỗi |
GetAsBinary(col) |
Đọc dữ liệu nhị phân |
BindParameterAsString(n, val) |
Ràng buộc tham số chuỗi |
BindParameterAsBinary(n, val) |
Ràng buộc tham số nhị phân |