KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

Error 2014 #2690

Closed Ron opened this topic on on May 21, 2022 - 18 comments

Ron commented on May 21, 2022

I updated my project with the latest KoolReport Pro v.5.16.2. I was using one version before and I did not change anything in my reports code. I started getting the following error of reports with Carts Widget:

Query Error >> ["HY000",2014,"Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute."] >> CALL chartTotalSubstitutesPerWeek(:year, :teacher_id, :date, :days) || Sql params = {":year":"5782",":teacher_id":"6",":date":"2022-05-21",":days":"1,2,3,4,5,6"} || Search params = []

KoolReport commented on May 22, 2022

Inside our PDODataSource, we do turn on the buffered (line 546 in PDODataSourcel.php)

        $mysqlBuffer = Util::get($this->params, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
        $this->connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $mysqlBuffer);

Could you please check if inside your connection config inside settings() function, you set any buffered query property there.

Ron commented on May 22, 2022

this is the settings function connection string.

"db"=>array(
                "connectionString"=>"mysql:host=localhost;dbname=mydb"
                "username"=>"",
                "password"=>"",
                "charset"=>"utf8"
            )
Ron commented on May 22, 2022

btw I am using now 5.16.1. version and not 5.16.2 as I mentioned

Sebastian Morales commented on May 23, 2022

Pls revert to KoolReport Pro 5.9.0 or koolreport/core 5.5.0 to see if this issue is changed.

Ron commented on May 23, 2022

don't have the old version. can you please send me a link for 5.9.0

Sebastian Morales commented on May 23, 2022

Do you install by composer or downloading zip file? In case of composer, just change the package version.

Ron commented on May 23, 2022

I usually download it from your website under My license

Sebastian Morales commented on May 23, 2022

Pls go to this link and download koolreport/core 5.5.0 and use it instead:

https://github.com/koolreport/core/releases/tag/v5.5.0

Ron commented on May 23, 2022

I did change the version to Koolreport 5.1.0 pro and it works fine. when I install the latest version 5.16.1 it has the same error as I mentioned.

Sebastian Morales commented on May 23, 2022

Thank you. Pls update to the latest version and apply the following fix: replace all in koolreport/core/src/datasources/PdoDataSource.php these lines:

        $mysqlBuffer = Util::get($this->params, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
        $this->connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $mysqlBuffer);

with these ones:

        if (isset($this->params[PDO::MYSQL_ATTR_USE_BUFFERED_QUERY])) {
            $mysqlBuffer = $this->params[PDO::MYSQL_ATTR_USE_BUFFERED_QUERY];
            $this->connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $mysqlBuffer);
        }

Let us know the result. Tks,

Ron commented on May 24, 2022

gives the same error

Sebastian Morales commented on May 24, 2022

Pls post your error's full stack trace for us to know exactly which line of code in which file is the reason.

Ron commented on May 24, 2022

here is the full stack trace

Sebastian Morales commented on May 24, 2022

Pls comment out all occurrences (there should be 2 times) the following commands in PdoDataSource.php

            // $mysqlBuffer = $this->params[PDO::MYSQL_ATTR_USE_BUFFERED_QUERY];
            // $this->connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $mysqlBuffer);

Let us know if this helps fixing the issue. Tks,

Ron commented on May 24, 2022

gives the same error even after comment out all the occurrences in PdoDataSource.php

Sebastian Morales commented on May 25, 2022

Pls try to replace your PdoDataSource.php content with the following code:

<?php

/**
 * This file contain class to handle pulling data from MySQL, Oracle, SQL Server and many others.
 *
 * @category  Core
 * @package   KoolReport
 * @author    KoolPHP Inc <support@koolphp.net>
 * @copyright 2017-2028 KoolPHP Inc
 * @license   MIT License https://www.koolreport.com/license#mit-license
 * @link      https://www.koolphp.net
 */

namespace koolreport\datasources;

use \koolreport\core\DataSource;
use \koolreport\core\Utility as Util;
use PDO;

/**
 * PDODataSource helps to connect to various databases such as MySQL, SQL Server or Oracle
 *
 * @category  Core
 * @package   KoolReport
 * @author    KoolPHP Inc <support@koolphp.net>
 * @copyright 2017-2028 KoolPHP Inc
 * @license   MIT License https://www.koolreport.com/license#mit-license
 * @link      https://www.koolphp.net
 */
class PdoDataSource extends DataSource
{
    /**
     * List of available connections for reusing
     *
     * @var array $connections List of available connections for reusing
     */
    public static $connections;

    /**
     * The current connection
     *
     * @var $connection The current connection
     */
    protected $connection;

    /**
     * The query
     *
     * @var string $query The query
     */
    protected $query;

    /**
     * The params of query
     *
     * @var array $sqlParams The params of query
     */
    protected $sqlParams;

    protected $queryParams;

    /**
     * Whether the total should be counted.
     *
     * @var bool $countToal Whether the total should be counted.
     */
    protected $countTotal;

    /**
     * Whether the filter should be counted
     *
     * @var bool $countFilter Whether the filter should be counted
     */
    protected $countFilter;


    /**
     * Store error info if there is
     * @var array
     */
    protected $errorInfo;


    /**
     * Datasource initiation
     *
     * @return null
     */
    protected function onInit()
    {
        // $this->connection = Util::get($this->params,"connection",null);
        $connectionString = Util::get($this->params, "connectionString", "");
        $username = Util::get($this->params, "username", "");
        $password = Util::get($this->params, "password", "");
        $charset = Util::get($this->params, "charset");
        $options = Util::get($this->params, "options");

        $key = md5($connectionString . $username . $password);
        if (PdoDataSource::$connections == null) {
            PdoDataSource::$connections = array();
        }
        if (isset(PdoDataSource::$connections[$key])) {
            $this->connection = PdoDataSource::$connections[$key];
        } else {
            $this->connection = new PDO(
                $connectionString,
                $username,
                $password,
                $options
            );

            PdoDataSource::$connections[$key] = $this->connection;
        }
        if ($charset) {
            $this->connection->exec("set names '$charset'");
        }
    }

    /**
     * Set the query and params
     *
     * @param string $query     The SQL query statement
     * @param array  $sqlParams The parameters of SQL query
     *
     * @return PdoDataSource This datasource object
     */
    public function query($query, $sqlParams = null)
    {
        $this->originalQuery = $this->query =  (string)$query;
        if ($sqlParams != null) {
            $this->sqlParams = $sqlParams;
        }
        return $this;
    }

    public function escapeStr($value)
    {
        return $this->connection->quote($value);
    }

    /**
     * Transform query
     *
     * @param array $queryParams Parameters of query
     *
     * @return null
     */
    public function queryProcessing($queryParams)
    {
        $this->queryParams = $queryParams;
        $driver = strtolower($this->connection->getAttribute(PDO::ATTR_DRIVER_NAME));
        //drivers = Array ( [0] => mysql [1] => oci [2] => pgsql [3] => sqlite [4] => sqlsrv )
        switch ($driver) {
            case 'mysql':
                list($this->query, $this->totalQuery, $this->filterQuery, $this->aggregates)
                    = MySQLDataSource::processQuery($this->originalQuery, $queryParams);
                break;
            case 'oci':
                list($this->query, $this->totalQuery, $this->filterQuery)
                    = OracleDataSource::processQuery($this->originalQuery, $queryParams);
                break;
            case 'pgsql':
                list($this->query, $this->totalQuery, $this->filterQuery)
                    = PostgreSQLDataSource::processQuery($this->originalQuery, $queryParams);
                break;
            case 'sqlsrv':
                list($this->query, $this->totalQuery, $this->filterQuery)
                    = SQLSRVDataSource::processQuery($this->originalQuery, $queryParams);
                break;
            default:
                break;
        }

        $this->countTotal = Util::get($queryParams, 'countTotal', false);
        $this->countFilter = Util::get($queryParams, 'countFilter', false);

        return $this;
    }

    /**
     * Insert params for query
     *
     * @param array $sqlParams The parameters for query
     *
     * @return OracleDataSource This datasource
     */
    public function params($sqlParams)
    {
        $this->sqlParams = $sqlParams;
        return $this;
    }

    /**
     * Prepare SQL statement
     *
     * @param string $query     Query need to bind params
     * @param array  $sqlParams The parameters will be bound to query
     *
     * @return string Procesed query
     */
    protected function prepareAndBind($query, $params)
    {
        if (empty($params)) {
            $params = [];
        }
        $paNames = array_keys($params);
        // Sort param names, longest name first,
        // so that longer ones are replaced before shorter ones in query
        // to avoid case when a shorter name is a substring of a longer name
        usort(
            $paNames,
            function ($k1, $k2) {
                return strlen($k2) - strlen($k1);
            }
        );
        // echo "paNames = "; print_r($paNames); echo "<br>";

        // Spread array parameters
        $query = $query;
        foreach ($paNames as $paName) {
            $paValue = $params[$paName];
            if (gettype($paValue) === "array") {
                $numValues = strlen((string)count($paValue));
                $paramList = [];
                foreach ($paValue as $i => $value) {
                    $order = $i + 1;
                    // Pad order to keep all array param name length equal
                    $order = str_pad($order, $numValues, "0", STR_PAD_LEFT);
                    $paArrElName = $paName . "_arr_$order";
                    $paramList[] = $paArrElName;
                    $params[$paArrElName] = $value;
                }
                $query = str_replace($paName, implode(",", $paramList), $query);
            }
        }

        $paNames = array_keys($params);
        usort(
            $paNames,
            function ($k1, $k2) {
                return strlen($k2) - strlen($k1);
            }
        );
        // echo "paNames = "; print_r($paNames); echo "<br><br>";
        // echo "query = $query<br><br>";
        // echo "params = "; print_r($params); echo "<br><br>";

        $newParams = [];
        $hashedPaNames = [];
        foreach ($paNames as $paName) {
            $count = 1;
            $pos = -1;
            while (true) {
                $pos = strpos($query, $paName, $pos + 1);
                if ($pos === false) {
                    break;
                } else {
                    $newPaName = $count > 1 ? $paName . "_" . $count : $paName;
                    $newParams[$newPaName] = $params[$paName];
                    // $hashedPaName = $newPaName;
                    $hashedPaName = md5($newPaName);
                    $hashedPaNames[$newPaName] = $hashedPaName;
                    $query = substr_replace($query, $hashedPaName, $pos, strlen($paName));
                }
                $count++;
            }
        }
        foreach ($newParams as $newPaName => $value) {
            $hashedPaName = $hashedPaNames[$newPaName];
            $query = str_replace($hashedPaName, $newPaName, $query);
        }

        // echo "query = $query<br><br>";
        // echo "newParams = "; print_r($newParams); echo "<br><br>";

        $stm = $this->connection->prepare($query);

        // $paramNum = 0;
        // $newParams[":a"] = 1;
        foreach ($newParams as $paName => $paValue) {
            $type = gettype($paValue);
            $paramType = $this->typeToPDOParamType($type);
            // echo "paramType=$paramType <br>";
            // echo "paValue=$paValue <br>";
            $stm->bindValue($paName, $paValue, $paramType);
        }
        
        return $stm;
    }

    /**
     * Convert type to PdoParamType
     *
     * @param string $type Type
     *
     * @return intger The PDO Param Type
     */
    protected function typeToPDOParamType($type)
    {
        switch ($type) {
            case "boolean":
                return PDO::PARAM_BOOL;
            case "integer":
                return PDO::PARAM_INT;
            case "NULL":
                return PDO::PARAM_NULL;
            case "resource":
                return PDO::PARAM_LOB;
            case "double":
            case "string":
            default:
                return PDO::PARAM_STR;
        }
    }

    /**
     * Guess type
     *
     * @param string $native_type Native type of PDO
     *
     * @return string KoolReport type
     */
    protected function guessType($native_type)
    {
        $map = array(
            "character" => "string",
            "char" => "string",
            "string" => "string",
            "str" => "string",
            "text" => "string",
            "blob" => "string",
            "binary" => "string",
            "enum" => "string",
            "set" => "string",
            "int" => "number",
            "double" => "number",
            "float" => "number",
            "long" => "number",
            "numeric" => "number",
            "decimal" => "number",
            "real" => "number",
            "tinyint" => "number",
            "bit" => "number",
            "boolean" => "number",
            "datetime" => "datetime",
            "date" => "date",
            "time" => "time",
            "year" => "datetime",
        );

        $native_type = strtolower($native_type);

        foreach ($map as $key => $value) {
            if (strpos($native_type, $key) !== false) {
                return $value;
            }
        }
        return "unknown";
    }

    /**
     * Guess type from value
     *
     * @param mixed $value The value
     *
     * @return string Type of value
     */
    protected function guessTypeFromValue($value)
    {
        $map = array(
            "float" => "number",
            "double" => "number",
            "int" => "number",
            "integer" => "number",
            "bool" => "number",
            "numeric" => "number",
            "string" => "string",
        );

        $type = strtolower(gettype($value));
        foreach ($map as $key => $value) {
            if (strpos($type, $key) !== false) {
                return $value;
            }
        }
        return "unknown";
    }

    protected function buildMetaData()
    {
        // echo "pdodatasource buildMetaData<br>";
        $metaData = array("columns" => array());

        if (empty($this->sqlParams)) $this->sqlParams = [];

        $searchParams = Util::get($this->queryParams, 'searchParams', []);
        if (empty($searchParams)) $searchParams = [];

        if ($this->countTotal) {
            $stm = $this->prepareAndBind($this->totalQuery, $this->sqlParams);
            $stm->execute();
            $error = $stm->errorInfo();
            if ($error[2] != null) {
                throw new \Exception(
                    "Query Error >> " . json_encode($error) . " >> $this->totalQuery"
                        . " || Sql params = " . json_encode($this->sqlParams)
                );
                return;
            }
            $row = $stm->fetch();
            $stm->closeCursor();
            $result = $row[0];
            $metaData['totalRecords'] = $result;
        }

        if ($this->countFilter) {
            $stm = $this->prepareAndBind($this->filterQuery, array_merge($this->sqlParams, $searchParams));
            $stm->execute();
            $error = $stm->errorInfo();
            if ($error[2] != null) {
                throw new \Exception(
                    "Query Error >> " . json_encode($error) . " >> $this->filterQuery"
                        . " || Sql params = " . json_encode($this->sqlParams)
                        . " || Search params = " . json_encode($searchParams)
                );
            }
            $row = $stm->fetch();
            $stm->closeCursor();
            $result = $row[0];
            $metaData['filterRecords'] = $result;
        }

        if (!empty($this->aggregates)) {
            foreach ($this->aggregates as $aggregate) {
                $operator = $aggregate["operator"];
                $field = $aggregate["field"];
                $aggQuery = $aggregate["aggQuery"];
                // $aggQuery = $this->prepareParams($aggQuery, $this->sqlParams);
                // $stm = $this->connection->prepare($aggQuery);
                // $this->bindParams($stm, $this->sqlParams);
                // $this->bindParams($stm, $searchParams);
                $stm = $this->prepareAndBind($aggQuery, array_merge($this->sqlParams, $searchParams));
                $stm->execute();
                $error = $stm->errorInfo();
                if ($error[2] != null) {
                    throw new \Exception(
                        "Query Error >> " . json_encode($error) . " >> $aggQuery"
                            . " || Sql params = " . json_encode($this->sqlParams)
                            . " || Search params = " . json_encode($searchParams)
                    );
                }
                $row = $stm->fetch();
                $stm->closeCursor();
                $result = $row[0];
                Util::set($metaData, ['aggregates', $operator, $field], $result);
            }
        }

        $driver = strtolower($this->connection->getAttribute(PDO::ATTR_DRIVER_NAME));
        $metaSupportDrivers = array('dblib', 'mysql', 'pgsql', 'sqlite');
        $metaSupport = false;
        foreach ($metaSupportDrivers as $supportDriver) {
            if (strpos($driver, $supportDriver) !== false) {
                $metaSupport = true;
            }
        }

        $query = $this->query;
        $this->stm = $this->prepareAndBind($query, array_merge($this->sqlParams, $searchParams));
        $this->stm->execute();

        $error = $this->stm->errorInfo();
        // if($error[2]!=null)
        if ($error[0] != '00000') {
            throw new \Exception(
                "Query Error >> " . json_encode($error) . " >> $query"
                    . " || Sql params = " . json_encode($this->sqlParams)
                    . " || Search params = " . json_encode($searchParams)
            );
        }

        $this->firstRow = null;
        if (!$metaSupport) {
            $this->firstRow = $this->stm->fetch(PDO::FETCH_ASSOC);
            $cNames = empty($row) ? array() : array_keys($row);
            $numcols = count($cNames);
        } else {
            $numcols = $this->stm->columnCount();
        }

        // $metaData = array("columns"=>array());
        for ($i = 0; $i < $numcols; $i++) {
            if (!$metaSupport) {
                $cName = $cNames[$i];
                $cType = $this->guessTypeFromValue($row[$cName]);
            } else {
                $info = $this->stm->getColumnMeta($i);
                $cName = $info["name"];
                $cType = $this->guessType(Util::get($info, "native_type", "unknown"));
            }
            $metaData["columns"][$cName] = array(
                "type" => $cType,
            );
            switch ($cType) {
                case "datetime":
                    $metaData["columns"][$cName]["format"] = "Y-m-d H:i:s";
                    break;
                case "date":
                    $metaData["columns"][$cName]["format"] = "Y-m-d";
                    break;
                case "time":
                    $metaData["columns"][$cName]["format"] = "H:i:s";
                    break;
            }
        }

        $this->builtMetaData = $metaData;
    }

    /**
     * Start piping data
     *
     * @return null
     */
    public function start()
    {
        // echo "pdodatasource start()<br>";
        if (isset($this->params[PDO::MYSQL_ATTR_USE_BUFFERED_QUERY])) {
            $mysqlBuffer = $this->params[PDO::MYSQL_ATTR_USE_BUFFERED_QUERY];
            $this->connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $mysqlBuffer);
        }

        $this->buildMetaData();
        $this->sendMeta($this->builtMetaData, $this);

        $this->startInput(null);

        if (!isset($this->firstRow)) {
            $row = $this->stm->fetch(PDO::FETCH_ASSOC);
        } else {
            $row = $this->firstRow;
        }

        while ($row) {
            $this->next($row, $this);
            $row = $this->stm->fetch(PDO::FETCH_ASSOC);
        }
        $this->endInput(null);
        $this->stm->closeCursor();
        $this->endOfStm = true;
    }

    public function startMetaOnly()
    {
        // echo "pdodatasource startMetaOnly<br>";
        if (!isset($this->builtMetaData)) {
            $this->buildMetaData();
            $this->sendMeta($this->builtMetaData, $this);
        }
    }

    public function startGenerator($genName)
    {
        // echo "pdodatasource startGenerator<br>";
        $this->startInput(null);

        $report = $this->getReport();
        $report->saveDataGenRow = $genName;

        if (isset($this->endOfStm) && $this->endOfStm === true) {
            $this->stm->execute();
            $this->firstRow = $this->stm->fetch(PDO::FETCH_ASSOC);
            $this->endOfStm = false;            
        }

        if (!isset($this->firstRow)) {
            $row = $this->stm->fetch(PDO::FETCH_ASSOC);
        } else {
            $row = $this->firstRow;
        }

        if (!isset($report->dataGenRow)) $report->dataGenRow = [];
        while ($row) {
            $this->next($row, $this);
            foreach ($report->dataGenRow as $outGenName => $rows) {
                if ($outGenName !== $genName) {
                    $report->dataGenRow[$outGenName] = [];
                    continue;
                }
                if (!empty($rows)) {
                    foreach ($rows as $row) yield $genName => $row;
                    $report->dataGenRow[$genName] = [];
                }
            }
            $row = $this->stm->fetch(PDO::FETCH_ASSOC);
        }
        $report->saveDataGenRow = null;
        $this->endInput(null);
        $this->endOfStm = true;
        $this->stm->closeCursor();
    }

    public function fetchFields($query)
    {
        $columns = [];
        // $query = $this->prepareParams($query, []);
        // $stm = $this->connection->prepare($query);
        $stm = $this->prepareAndBind($query, $this->sqlParams);
        $stm->execute();
        $error = $stm->errorInfo();
        // if($error[2]!=null)
        if ($error[0] != '00000') {
            throw new \Exception(
                "Query Error >> " . json_encode($error) . " >> $query"
            );
        }
        $driver = strtolower($this->connection->getAttribute(PDO::ATTR_DRIVER_NAME));
        $metaSupportDrivers = array('dblib', 'mysql', 'pgsql', 'sqlite');
        $metaSupport = false;
        foreach ($metaSupportDrivers as $supportDriver) {
            if (strpos($driver, $supportDriver) !== false) {
                $metaSupport = true;
            }
        }

        if (!$metaSupport) {
            $row = $stm->fetch(PDO::FETCH_ASSOC);
            $cNames = empty($row) ? array() : array_keys($row);
            $numcols = count($cNames);
        } else {
            $numcols = $stm->columnCount();
        }

        // $metaData = array("columns"=>array());
        for ($i = 0; $i < $numcols; $i++) {
            if (!$metaSupport) {
                $cName = $cNames[$i];
                $cType = $this->guessTypeFromValue($row[$cName]);
            } else {
                $info = $stm->getColumnMeta($i);
                $cName = $info["name"];
                $cType = $this->guessType(Util::get($info, "native_type", "unknown"));
            }
            $columns[$cName] = array(
                "type" => $cType,
            );
            switch ($cType) {
                case "datetime":
                    $columns[$cName]["format"] = "Y-m-d H:i:s";
                    break;
                case "date":
                    $columns[$cName]["format"] = "Y-m-d";
                    break;
                case "time":
                    $columns[$cName]["format"] = "H:i:s";
                    break;
            }
        }
        $stm->closeCursor();
        return $columns;
    }

    public function fetchData($query, $queryParams = null)
    {
        if (
            isset($queryParams) &&
            (isset($queryParams['countTotal']) || isset($queryParams['countFilter']))
        ) {
            $driver = strtolower($this->connection->getAttribute(PDO::ATTR_DRIVER_NAME));
            switch ($driver) {
                case 'mysql':
                    list($query, $totalQuery, $filterQuery)
                        = MySQLDataSource::processQuery($query, $queryParams);
                    break;
                case 'oci':
                    list($query, $totalQuery, $filterQuery)
                        = OracleDataSource::processQuery($query, $queryParams);
                    break;
                case 'pgsql':
                    list($query, $totalQuery, $filterQuery)
                        = PostgreSQLDataSource::processQuery($query, $queryParams);
                    break;
                case 'sqlsrv':
                    list($query, $totalQuery, $filterQuery)
                        = SQLSRVDataSource::processQuery($query, $queryParams);
                    break;
                default:
                    break;
            }
            $queries = [
                'data' => $query,
                'total' => $totalQuery,
                'filter' => $filterQuery
            ];
        } else {
            $queries = [
                'data' => $query
            ];
        }
        // echo "fetData queries = "; Util::prettyPrint($queries);
        $result = [];
        foreach ($queries as $key => $query) {
            // $query = $this->prepareParams($query, $this->sqlParams);
            // $stm = $this->connection->prepare($query);
            // $this->bindParams($stm, $this->sqlParams);
            $stm = $this->prepareAndBind($query, $this->sqlParams);
            $stm->execute();

            $error = $stm->errorInfo();
            // if($error[2]!=null)
            if ($error[0] != '00000') {
                throw new \Exception(
                    "Query Error >> " . json_encode($error) . " >> $query"
                        . " || Sql params = " . json_encode($this->sqlParams)
                );
            }

            $rows = [];
            while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
                $rows[] = $row;
            }

            $result[$key] = $rows;
        }
        $stm->closeCursor();
        return $result;
    }

    public function errorInfo()
    {
        return $this->errorInfo;
    }

    /**
     * General way to execute a query
     * @param mixed $sql 
     * @return boolean Whether the sql is succesfully executed 
     */
    public function execute($sql, $params = null)
    {
        if (is_array($params)) {
            //Need prepare
            // $stm = $this->connection->prepare($sql);
            // $success = $stm->execute($params);
            $stm = $this->prepareAndBind($sql, $params);
            $success = $stm->execute();
            if ($success === false) {
                $this->errorInfo = $stm->errorInfo();
            } else {
                $this->errorInfo = null;
            }
        } else {
            $success = $this->connection->exec($sql);
            if ($success === false) {
                $this->errorInfo = $this->connection->errorInfo();
            } else {
                $this->errorInfo = null;
            }
        }
        $stm->closeCursor();
        return $success !== false;
    }
}
 
Ron commented on May 25, 2022

Its is working now. will you include this fix in the next version that will come out?

Sebastian Morales commented on May 25, 2022

We will do. Tks,

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
None yet

None