Jump to content
Дизайн и модификация IPS Community IPBSkinsBETA
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
HooLIGUN

sql запрос в оболочке ips

Recommended Posts

Подскажите, как сделать запрос в базу (возможно даже стороннюю).

В ipb 3.4 делал так

Циклы:

$this->DB->build( array(	
'select'	=> '*',
'from'		=> 'table',
'where'		=> 'member_id = "1"',
'order'		=> '`date` desc limit 10'
) );
$this->DB->execute();
while( $ac= $this->DB->fetch() ) {
	code...
}

Одиночный запрос

$data = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => '`table`', 'where' => "`id` = '{$id}'" ) );

Insert

$this->DB->query("INSERT INTO `table` VALUES ('id','name')");

Подскажите аналогичные функции в IPS 4

Вроде как тут описано https://invisioncommunity.com/developers/docs/fundamentals/accessing-the-database-r166/ , но не понял, как составить запрос и вывести данные

Share this post


Link to post

По указанной же ссылке все написано, что нужно. Даже соединение с удаленной БД.

9 часов назад, HooLIGUN сказал:

Циклы:

$select = \IPS\Db::i()->select( '*', 'table', array( 'member_id=?', 10 ), '`date` desc', array( 0, 10 ) );

Дальше используйте foreach

foreach ($select as $row)
{
}

Если с данными ничего не нужно делать, то можно использовать iterator_to_array

$rows = iterator_to_array( \IPS\Db::i()->select( '*', 'table', array( 'member_id=?', 10 ), '`date` desc', array( 0, 10 ) ) );

 

9 часов назад, HooLIGUN сказал:

Одиночный запрос

try
{
    $data = \IPS\Db::i()->select( '*', 'table', array( 'id=?', $id ) )->first();
}
catch( \UnderflowException $e )
{
    
}

 

9 часов назад, HooLIGUN сказал:

Insert

\IPS\Db::i()->insert( 'table', array( 'column_one' => 'value', 'column_two' => 'value2' ) );

 

  • Upvote 1

Share this post


Link to post
1 час назад, newbie сказал:

Даже соединение с удаленной БД.

Не прям удаленной. БД висят на одном хосте и на одном и том же пользователе, что и БД форума

Раньше я писал запрос. например select * from `otherbd`.`members`, `forum`.`members` .... и работал запрос из разных баз. 

Сейчас при написании такого запроса в функции select(), как я понял автоматически подставляется вперед бд форума

$select = \IPS\Db::i()->select( '*', 'match.matches' );
	SELECT * FROM `match.matches`
IPS\Db\Exception: Table 'forum.match.matches' doesn't exist (1146)

С кавычками ``

$select = \IPS\Db::i()->select( '*', '`match`.`matches`' );
	SELECT * FROM ``match`.`matches``
IPS\Db\Exception: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'match`.`matches``' at line 1 (1064)

Share this post


Link to post

Вот же пример из документации 

$connection = \IPS\Db::i( 'external', array(
    'sql_host'        => 'localhost',
    'sql_user'        => 'username',
    'sql_pass'        => 'password',
    'sql_database'    => 'database_name',
    'sql_port'        => 3306,
    'sql_socket'    => '/var/lib/mysql.sock',
    'sql_utf8mb4'    => true,
) );

Потом пишите 

$select = $connection->select( '*', 'matches' );

 

Share this post


Link to post

Спасибо, думал можно обойтись без повторного подключения

Edited by HooLIGUN

Share this post


Link to post
14 минут назад, newbie сказал:

Вот же пример из документации 


$connection = \IPS\Db::i( 'external', array(
    'sql_host'        => 'localhost',
    'sql_user'        => 'username',
    'sql_pass'        => 'password',
    'sql_database'    => 'database_name',
    'sql_port'        => 3306,
    'sql_socket'    => '/var/lib/mysql.sock',
    'sql_utf8mb4'    => true,
) );

Потом пишите 


$select = $connection->select( '*', 'matches' );

 

IPS\Db\Exception: No such file or directory (2002)
Edited by HooLIGUN
не смог отредактировать данный пост, курсора нет. Проблема была в sql_socket

Share this post


Link to post

@newbie, подскажите пожалуйста, что не так?

	Запрос отработал
	foreach ($data as $row) {
	try
{
$getsrv = $connection->select( 'name', 'servers', array( 'id=?', $row['serverid'] ) )->first();
}
catch( \UnderflowException $e )
{
        echo $e->getMessage();
        echo 'error?!';
}
	}

Выходит "error?!" , описания ошибки нет.

Нужно запросить и вывести name для каждого цикла

 

upd:

Решил, был некорректный ид в базе)

Edited by HooLIGUN

Share this post


Link to post

 

10 часов назад, HooLIGUN сказал:

подскажите пожалуйста, что не так?

Ну как минимум то, что запрос выполняются в цикле. На каждую итерацию будет приходить по одному sql запросу, когда можно одним sql запросом запросить сразу все данные.

$result = iterator_to_array( $connection->select('name', 'servers', $connection->in( 'id', array_column($data, 'serverid') ) );

 

Share this post


Link to post

Добрый день, подскажите, как сделать, чтобы при пустом результате запроса скрипт не выбивал ошибку

UnderflowException in /var/www/dev/data/www/.ru/system/Db/Select.php:370
Stack trace:
#0 /var/www/dev/data/www/.ru/scripts/result.php(48): IPS\Db\_Select->first()
#1 {main}

 

	try
            {
            $row = $connection->select( 'status', 'list', array( 'member_id=?', $memberid) )->first();
	            }
            catch( \UnderflowException $e )
            {
            echo $e;
            }
	

 

UPD

            try
            {
            $row = $connection->select( 'status', 'list', array( 'member_id=?', $memberid) )->first();
            }
            catch( \UnderflowException $e )
            {
            $row = array();
            }

Сделал так. Работает.

Edited by HooLIGUN

Share this post


Link to post

Подскажите пожалуйста, как адаптировать такой запрос в IPS4 ?

guard - сторонняя БД, но с доступом, как у пользователя форума

$this->DB->build( array(    
    'select'    => 'l.member_id,l.steamid,l.reason,l.create,l.end,
    m.members_display_nam,
    p.pp_thumb_photo as avatar,
    s.date as lastdate',
    'from'        => 'guard.ac_list l,forum.members m ,forum.profile_portal p,guard.ac_status s ',
    'where'        => ' 
    l.status = "1"  
    and l.member_id = m.member_id 
    and l.member_id = p.pp_member_id 
    and s.playerid = l.member_id',
    'order'        => '`create` desc limit '.$start_from.', '.$limit.''
    ) );
    $this->DB->execute();
    while( $ac= $this->DB->fetch() ) {
	}
	
Edited by HooLIGUN

Share this post


Link to post

С межбазовым запросом проще написать нативный sql и выполнить его через метод \IPS\Db::i()->query().
Конструктор обрамляет имя таблицы в обратные кавычки и указать таблицу из сторонней базы затруднительно в этом случае.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...