witam, w jaki sposób mogę ten kod przerobić zeby czytało account_id z accounts.
kod wyglada tak
query << "SELECT `name` FROM `players` WHERE `account_id` = " << accno;
witam, w jaki sposób mogę ten kod przerobić zeby czytało account_id z accounts.
kod wyglada tak
query << "SELECT `name` FROM `players` WHERE `account_id` = " << accno;
zrobiłem to tak
query << "SELECT `name` FROM `players` WHERE `account_id` FROM `accounts` = " << accno << " AND `deleted` = 0 FROM `players` ";
error mysql_real_query<>: SELECT
nameFROM
playersWHERE
account_idFROM
accounts= 123 AND
deleted= 0 FROM
players- MYSQL ERROR: you have an error in your SQL syntax: check the manual that corresponds to your MySQL serwer version for the right syntax to use near FROM
accounts= 123 AND
deleted= 0 FROM
players at line 1 <1064>
pomoże ktoś?
query << "SELECT account_id
FROM nazwa_tabeli
WHERE account_id
= " << accno;
// PL:
Wybierz z bazy danych 'account_id' Z tabeli ... GDZIE account_id jest równe accno
pomoże ktoś? OMG
??????????
ciągle potrzebuje pomocy
query << "SELECT `name` FROM `players` WHERE `account_id` = " << accno << " AND `deleted` = 0";
if(!(result = db->storeQuery(query.str())))
return account;
do
{
std::string ss = result->getDataString("name");
account.charList.push_back(ss.c_str());
}
chce w tym kodzie zeby account_id czytało z accounts
w tej chwili czyta z players ten kto sie zna to rozumie kod i nie muszę tłumaczyć
Grubo ... poczytaj najpierw o złączeniach tabel @Shakaz ma rację rozwiązanie masz podane ale nie masz gotowca i wydaje Ci się, że rozwiązania brak. Nie znam bazy danych, która mogłaby zrobić select coś from coś where coś from
Jeżeli faktycznie chcesz tabelę players połączyć z accounts to musisz użyć JOIN czyli np tak:
select cos from tab1 inner join tab2 on (tab1.IDPolaDoZlaczenia = Tab2.IDPolaDoZlaczeniaZTab1PrawdopodobnieForeginKey) where cos
Nie podałeś struktury, nie zrobiłeś przykładu na sql fiddle, nie podałeś nawet co chcesz uzyskać i dziwisz się, że nikt Ci gotowca nie daje ...
woolfik napisał(a):
Grubo ... poczytaj najpierw o złączeniach tabel @Shakaz ma rację rozwiązanie masz podane ale nie masz gotowca i wydaje Ci się, że rozwiązania brak. Nie znam bazy danych, która mogłaby zrobić select coś from coś where coś from
Jeżeli faktycznie chcesz tabelę players połączyć z accounts to musisz użyć JOIN czyli np tak:
select cos from tab1 inner join tab2 on (tab1.IDPolaDoZlaczenia = Tab2.IDPolaDoZlaczeniaZTab1PrawdopodobnieForeginKey) where cos
Nie podałeś struktury, nie zrobiłeś przykładu na sql fiddle, nie podałeś nawet co chcesz uzyskać i dziwisz się, że nikt Ci gotowca nie daje ...
to mi podaj opcje jak mogę coś takiego zrobić żeby działało w 100% tylko przykład
może zrobic 3x query? do każdego zapytania osobno czy lepiej tym joinem
jestem troche zielony ale co do tamtego postu to **** przecież koleś przekopiował to samo co miałem w pierwszym poście tylko zmienił z angielskiego na polski boshe...
Ech podaj nam tutaj DDL (kod obiektów sql czyli CREATE TABLE ...) obu tabel players i accounts to zobaczę co się da zrobić
woolfik napisał(a):
Ech podaj nam tutaj DDL (kod obiektów sql czyli CREATE TABLE ...) obu tabel players i accounts to zobaczę co się da zrobić
accounts
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for accounts
-- ----------------------------
DROP TABLE IF EXISTS `accounts`;
CREATE TABLE `accounts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL DEFAULT '',
`password` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1528016 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of accounts
-- ----------------------------
DROP TRIGGER IF EXISTS `ondelete_accounts`;
DELIMITER ;;
CREATE TRIGGER `ondelete_accounts` BEFORE DELETE ON `accounts` FOR EACH ROW BEGIN
DELETE FROM `bans` WHERE `type` IN (3, 4) AND `value` = OLD.`id`;
END
;;
DELIMITER ;
players
DROP TABLE IF EXISTS `players`;
CREATE TABLE `players` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`account_id` int(11) NOT NULL DEFAULT '0',
`deleted` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`,`deleted`),
KEY `account_id` (`account_id`),
KEY `deleted` (`deleted`),
CONSTRAINT `players_ibfk_1` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
wydaje mi się, że coś takiego powinno wystarczyć:
select p.name from accounts a inner join players p on (a.id = p.account_id) where p.deleted = 0 and a.account_id = <co tam chcesz>
Ewentualnie jeśli może się zdarzyć, że nie ma odpowiednika dla tabeli accounts w tabeli players to możesz inner join zmienić na left outer join ale wydaje mi się, że nie trzeba.
woolfik napisał(a):
wydaje mi się, że coś takiego powinno wystarczyć:
select p.name from accounts a inner join players p on (a.id = p.account_id) where p.deleted = 0 and a.account_id = <co tam chcesz>
Ewentualnie jeśli może się zdarzyć, że nie ma odpowiednika dla tabeli accounts w tabeli players to możesz inner join zmienić na left outer join ale wydaje mi się, że nie trzeba.
error
@Programistyczny ahhh i mamy Ci wywrozyc cos Ty tam narobil tak? ahhh... to blad jest w piatej linijce tej funkcji ktorej wywolujesz.
Problem masz ze zle utworzyles zapytanie i masz problem przez to ze skladnia (a raczej mysql ma)
fasadin napisał(a):
@Programistyczny ahhh i mamy Ci wywrozyc cos Ty tam narobil tak? ahhh... to blad jest w piatej linijce tej funkcji ktorej wywolujesz.
Problem masz ze zle utworzyles zapytanie i masz problem przez to ze skladnia (a raczej mysql ma)
dobrze zrobiłem
query << "SELECT p.name FROM accounts a INNER JOIN players p ON (a.id = p.account_id) WHERE p.deleted = 0 AND a.account_id = ";
Ja dobrze widzę, że za =
w AND a.account_id
nie ma niczego?
hipekk napisał(a):
Ja dobrze widzę, że za
=
wAND a.account_id
nie ma niczego?
a teraz? co jest zle
account_id
jest wieloznaczna (występuje zarówno w tabeli accounts
jak i players
). Chyba p.account_id
chciałeś użyć.hipekk napisał(a):
- Wklejaj swoje zapytanie a nie treść błędu
- Masz jasno napisane: kolumna
account_id
jest wieloznaczna. Chybap.account_id
chciałeś użyć.
kod
query << "SELECT p.name FROM accounts a INNER JOIN players p ON (a.id = p.account_id) WHERE p.deleted = 0 AND a.account_id = account_id";
taki jest kod
ma być = p.account_id?
@fasadin przepraszam ;]
Jeżeli wklepiesz a.account_id = p.account_id
to zapytanie powinno działać, ale wydaje mi się, że nie o to Ci chodzi.
Wychodzi na to że chcesz wyniki w których a.id = p.account_id = a.account_id
?
hipekk napisał(a):
Jeżeli wklepiesz
a.account_id = p.account_id
to zapytanie powinno działać, ale wydaje mi się, że nie o to Ci chodzi.
Wychodzi na to że chcesz wyniki w którycha.id = p.account_id = a.account_id
?
chodzi mi dokładnie o to co w pierwszym poście napisałem chce zmienić account_id z players na name z accounts
zmieniłem na account_id na p.account_id to teraz wyskakuje ze zła nazwa konta i hasło
query << "SELECT p.name FROM accounts a INNER JOIN players p ON (a.id = p.account_id) WHERE p.deleted = 0 AND a.account_id = p.account_id";
zmieniłem na account_id na p.account_id to teraz wyskakuje ze zła nazwa konta i hasło
To wpisz poprawne dane.
chce zmienić account_id z players na name z accounts
Chcesz w miejsce id wstawić nazwę?
Jesteś pewny, że to ten sam typ danych?
@Programistyczny to jest jakis czeski film co robisz. Skoro łączysz a.id = p.account_id
to ten ostatni warunek where jest albo głupi albo w ogóle niepotrzebny...
Weź parę głębokich wdechów i spróbuj tego:
query << "SELECT p.name FROM accounts a INNER JOIN players p ON (a.id = p.account_id) WHERE p.deleted = 0 AND a.account_id ="<< accno;
EroSanin napisał(a):
Weź parę głębokich wdechów i spróbuj tego:
query << "SELECT p.name FROM accounts a INNER JOIN players p ON (a.id = p.account_id) WHERE p.deleted = 0 AND a.account_id ="<< accno;
wyskakuje ze złe hasło lub nazwa konta a wpisuję w 100% dobre
No to usługodawca Cię oszukuje :P.
Pokaż cały kod (oczywiście wrażliwe dane zmień).
cały kod wygląda tak
to jest orginal bez ruszania
#include "ioaccountsql.h"
#include <iostream>
#include <iomanip>
#include "tools.h"
#include "database.h"
Account IOAccountSQL::loadAccount(uint32_t accno)
{
Account account;
time_t lastDay;
Database* db = Database::getInstance();
DBQuery query;
query << "SELECT `id`, `password`, `premdays`, `rkey`, `email`, `premium_points` FROM `accounts` WHERE `id` = " << accno << " LIMIT 1";
DBResult* result;
if(!(result = db->storeQuery(query.str())))
return account;
account.accnumber = result->getDataInt("id");
account.password = result->getDataString("password");
account.premDays = result->getDataInt("premdays");
account.key = result->getDataString("rkey");
account.email = result->getDataString("email");
account.premium_points = result->getDataInt("premium_points");
query.str("");
result->free();
//i tutaj zmienialem
//orginal query << "SELECT `name` FROM `players` WHERE `account_id` = " << accno << " AND `deleted` = 0";
query << "SELECT p.name FROM accounts a INNER JOIN players p ON (a.id = p.account_id) WHERE p.deleted = 0 AND a.account_id ="<< accno;
if(!(result = db->storeQuery(query.str())))
return account;
do
{
std::string ss = result->getDataString("name");
account.charList.push_back(ss.c_str());
}
while(result->next());
result->free();
account.charList.sort();
return account;
}
bool IOAccountSQL::saveAccount(Account account)
{
Database* db = Database::getInstance();
DBQuery query;
query << "UPDATE `accounts` SET `premdays` = " << account.premDays << ", `email` = '" << account.email << "', `premium_points` = " << account.premium_points << " WHERE `id` = " << account.accnumber << db->getUpdateLimiter();
return db->executeQuery(query.str());
}
bool IOAccountSQL::getPassword(uint32_t accno, const std::string &name, std::string &password)
{
Database* db = Database::getInstance();
DBQuery query;
query << "SELECT `password` FROM `accounts` WHERE `id` = " << accno << " LIMIT 1";
DBResult* result;
if(!(result = db->storeQuery(query.str())))
return false;
if(name.empty())
{
password = result->getDataString("password");
result->free();
return true;
}
std::string tmpPassword = result->getDataString("password");
result->free();
query.str("");
query << "SELECT `name` FROM `players` WHERE `account_id` = " << accno;
if(!(result = db->storeQuery(query.str())))
return false;
do
{
if(result->getDataString("name") != name)
continue;
password = tmpPassword;
result->free();
return true;
}
while(result->next());
result->free();
return false;
}
bool IOAccountSQL::accountExists(uint32_t accno)
{
Database* db = Database::getInstance();
DBQuery query;
query << "SELECT `id` FROM `accounts` WHERE `id` = " << accno << " LIMIT 1";
DBResult* result;
if(!(result = db->storeQuery(query.str())))
return false;
result->free();
return true;
}
database.h
#include "scheduler.h"
#include "database.h"
#include "databasemysql.h"
#ifdef __MYSQL_ALT_INCLUDE__
#include "errmsg.h"
#else
#include <mysql/errmsg.h>
#endif
#include <iostream>
#include "luascript.h"
#include "game.h"
extern LuaScript g_config;
extern Game g_game;
DatabaseMySQL::DatabaseMySQL()
{
m_connected = false;
if(!mysql_init(&m_handle))
{
std::cout << std::endl << "Failed to initialize MySQL connection handler." << std::endl;
return;
}
uint32_t readTimeout = g_config.MYSQL_READ_TIMEOUT;
if(readTimeout)
mysql_options(&m_handle, MYSQL_OPT_READ_TIMEOUT, (const char*)&readTimeout);
uint32_t writeTimeout = g_config.MYSQL_WRITE_TIMEOUT;
if(writeTimeout)
mysql_options(&m_handle, MYSQL_OPT_WRITE_TIMEOUT, (const char*)&writeTimeout);
connect();
if(mysql_get_client_version() <= 50019)
{
//MySQL servers <= 5.0.19 has a bug where MYSQL_OPT_RECONNECT is (incorrectly) reset by mysql_real_connect calls
//See http://dev.mysql.com/doc/refman/5.0/en/mysql-options.html for more information.
std::cout << std::endl << "> WARNING: Outdated MySQL server detected, consider upgrading to a newer version." << std::endl;
}
int32_t keepAlive = g_config.SQL_KEEPALIVE;
if(keepAlive)
g_game.addEvent(makeTask((keepAlive * 1000), boost::bind(&DatabaseMySQL::keepAlive, this)));
}
bool DatabaseMySQL::getParam(DBParam_t param)
{
switch(param)
{
case DBPARAM_MULTIINSERT:
return true;
default:
break;
}
return false;
}
bool DatabaseMySQL::rollback()
{
if(!m_connected)
return false;
if(mysql_rollback(&m_handle))
{
std::cout << "mysql_rollback() - MYSQL ERROR: " << mysql_error(&m_handle) << " (" << mysql_errno(&m_handle) << ")" << std::endl;
return false;
}
return true;
}
bool DatabaseMySQL::commit()
{
if(!m_connected)
return false;
if(mysql_commit(&m_handle))
{
std::cout << "mysql_commit() - MYSQL ERROR: " << mysql_error(&m_handle) << " (" << mysql_errno(&m_handle) << ")" << std::endl;
return false;
}
return true;
}
bool DatabaseMySQL::executeQuery(const std::string &query)
{
if(!m_connected)
return false;
bool state = true;
if(mysql_real_query(&m_handle, query.c_str(), query.length()))
{
int32_t error = mysql_errno(&m_handle);
if((error == CR_UNKNOWN_ERROR || error == CR_SERVER_LOST || error == CR_SERVER_GONE_ERROR) && reconnect())
return executeQuery(query);
state = false;
std::cout << "mysql_real_query(): " << query << " - MYSQL ERROR: " << mysql_error(&m_handle) << " (" << error << ")" << std::endl;
}
if(MYSQL_RES* tmp = mysql_store_result(&m_handle))
{
mysql_free_result(tmp);
tmp = NULL;
}
return state;
}
DBResult* DatabaseMySQL::storeQuery(const std::string &query)
{
if(!m_connected)
return NULL;
int32_t error = 0;
if(mysql_real_query(&m_handle, query.c_str(), query.length()))
{
error = mysql_errno(&m_handle);
if((error == CR_UNKNOWN_ERROR || error == CR_SERVER_LOST || error == CR_SERVER_GONE_ERROR) && reconnect())
return storeQuery(query);
std::cout << "mysql_real_query(): " << query << " - MYSQL ERROR: " << mysql_error(&m_handle) << " (" << error << ")" << std::endl;
return NULL;
}
if(MYSQL_RES* tmp = mysql_store_result(&m_handle))
{
DBResult* res = (DBResult*)new MySQLResult(tmp);
return verifyResult(res);
}
error = mysql_errno(&m_handle);
if((error == CR_UNKNOWN_ERROR || error == CR_SERVER_LOST || error == CR_SERVER_GONE_ERROR) && reconnect())
return storeQuery(query);
std::cout << "mysql_store_result(): " << query << " - MYSQL ERROR: " << mysql_error(&m_handle) << " (" << error << ")" << std::endl;
return NULL;
}
std::string DatabaseMySQL::escapeBlob(const char* s, uint32_t length)
{
if(!s)
return "''";
char* output = new char[length * 2 + 1];
mysql_real_escape_string(&m_handle, output, s, length);
std::string res = "'";
res += output;
res += "'";
delete[] output;
return res;
}
void DatabaseMySQL::keepAlive()
{
int32_t delay = g_config.SQL_KEEPALIVE;
if(delay)
{
if(time(NULL) > (m_use + delay) && mysql_ping(&m_handle))
reconnect();
g_game.addEvent(makeTask((delay * 1000), boost::bind(&DatabaseMySQL::keepAlive, this)));
}
}
bool DatabaseMySQL::connect()
{
if(m_connected)
{
m_connected = false;
mysql_close(&m_handle);
}
if(!mysql_real_connect(&m_handle, g_config.SQL_HOST.c_str(), g_config.SQL_USER.c_str(),
g_config.SQL_PASS.c_str(), g_config.SQL_DB.c_str(), g_config.SQL_PORT, NULL, 0))
{
std::cout << "Failed connecting to database - MYSQL ERROR: " << mysql_error(&m_handle) << " (" << mysql_errno(&m_handle) << ")" << std::endl;
return false;
}
m_connected = true;
m_attempts = 0;
return true;
}
bool DatabaseMySQL::reconnect()
{
while(m_attempts <= MAX_RECONNECT_ATTEMPTS)
{
m_attempts++;
if(connect())
return true;
}
std::cout << "Unable to reconnect - too many attempts, limit exceeded!" << std::endl;
return false;
}
int32_t MySQLResult::getDataInt(const std::string &s)
{
listNames_t::iterator it = m_listNames.find(s);
if(it != m_listNames.end())
{
if(!m_row[it->second])
return 0;
return atoi(m_row[it->second]);
}
if(refetch())
return getDataInt(s);
std::cout << "Error during getDataInt(" << s << ")." << std::endl;
return 0; // Failed
}
uint64_t MySQLResult::getDataLong(const std::string &s)
{
listNames_t::iterator it = m_listNames.find(s);
if(it != m_listNames.end())
{
if(!m_row[it->second])
return 0;
return atoll(m_row[it->second]);
}
if(refetch())
return getDataLong(s);
std::cout << "Error during getDataLong(" << s << ")." << std::endl;
return 0; // Failed
}
std::string MySQLResult::getDataString(const std::string &s)
{
listNames_t::iterator it = m_listNames.find(s);
if(it != m_listNames.end())
{
if(!m_row[it->second])
return "";
return std::string(m_row[it->second]);
}
if(refetch())
return getDataString(s);
std::cout << "Error during getDataString(" << s << ")." << std::endl;
return ""; // Failed
}
const char* MySQLResult::getDataStream(const std::string &s, uint64_t &size)
{
listNames_t::iterator it = m_listNames.find(s);
if(it != m_listNames.end())
{
if(!m_row[it->second])
{
size = 0;
return NULL;
}
size = mysql_fetch_lengths(m_handle)[it->second];
return m_row[it->second];
}
if(refetch())
return getDataStream(s, size);
std::cout << "Error during getDataStream(" << s << ")." << std::endl;
size = 0;
return NULL; // Failed
}
void MySQLResult::free()
{
if(m_handle)
{
mysql_free_result(m_handle);
m_handle = NULL;
m_listNames.clear();
delete this;
}
else
std::cout << "[Warning - MySQLResult::free] Trying to free already freed result." << std::endl;
}
bool MySQLResult::next()
{
m_row = mysql_fetch_row(m_handle);
return m_row;
}
void MySQLResult::fetch()
{
m_listNames.clear();
int32_t i = 0;
MYSQL_FIELD* field;
while((field = mysql_fetch_field(m_handle)))
m_listNames[field->name] = i++;
}
bool MySQLResult::refetch()
{
if(m_attempts >= MAX_REFETCH_ATTEMPTS)
return false;
fetch();
++m_attempts;
return true;
}
MySQLResult::MySQLResult(MYSQL_RES* result)
{
m_attempts = 0;
if(result)
{
m_handle = result;
fetch();
}
else
delete this;
}
A tak zapytam jeszcze: łączysz się z bazą lokalną czy na zewnątrz? Próbowałeś połączyć się z tą bazą (używając tych samych danych) z innego programu?