Stored procedures Yii2是使用MS SQL存储过程时的最佳实现

Stored procedures Yii2是使用MS SQL存储过程时的最佳实现,stored-procedures,yii,yii2,Stored Procedures,Yii,Yii2,我需要关于在存储过程中使用yii2的最佳方法的建议。因为这个区域非常灰色 我目前有一个yii1项目实现,和任何开发人员一样,我们总是在寻找新的方法来加快速度,编写比前一天更好的代码 我想启动我的新应用程序并将其移植到yii2,我想知道使用存储过程的最佳方式是什么,因为这是组织中当前的体系结构,而且我想直接使用Yii活动记录与数据库交互,但这是不可能的 因此,在我当前的yii1项目中,我在component中创建了一个类,并将其导入config/main.php中 'import' => a

我需要关于在存储过程中使用yii2的最佳方法的建议。因为这个区域非常灰色

我目前有一个yii1项目实现,和任何开发人员一样,我们总是在寻找新的方法来加快速度,编写比前一天更好的代码

我想启动我的新应用程序并将其移植到yii2,我想知道使用存储过程的最佳方式是什么,因为这是组织中当前的体系结构,而且我想直接使用Yii活动记录与数据库交互,但这是不可能的

因此,在我当前的yii1项目中,我在component中创建了一个类,并将其导入config/main.php中

'import' => array(
            'application.models.*',
            'application.components.SqlResource.*',
        ),
然后我开始把我的班级建设成

class SqlResource extends CApplicationComponent {

    const LOG_CAT = "ext.SqlResource";

    public $resources = array();
    public $db;
    public $mssql;

    /**
     * __construct
     *
     * @access public
     * @return void
     */
    public function __construct() {
        $serverUrl = Yii::app()->params->mssql['host'];
        $serverUser = Yii::app()->params->mssql['user'];
        $serverPass = Yii::app()->params->mssql['password'];
        $serverDb = Yii::app()->params->mssql['db_name'];
        try {
            $this->mssql = new PDO('dblib:host=' . $serverUrl . ';dbname=' . $serverDb, $serverUser, $serverPass);
            $this->mssql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            Yii::log("Connection Error: @(DB connection was unavailable )[" . $e->getMessage() . "] ", "error", self::LOG_CAT);
            die($e->getMessage());
        }
    }


/**
 *
 * @param type $data array containg username and password from the login form
 * @return array
 */
public function ExampleSqlResourceFunction($username, $password) {
    if (!empty($username) && is_string($username)) {
        $procedure = "exec login_access @username = :username, @password = :password"; //Procedure to be called
        $query = $this->mssql->prepare($procedure); //PDO prepare a query for execution  using bind parameters to avaid leve 1 and level 2 sql injection
        $start = array_sum(explode(' ', round(microtime(TRUE) * 1000))); //start time to  calculate the time it takes to execute a query. the log time is logged for debugging process
        $query->bindValue(":username", $username, PDO::PARAM_STR); //bind the alias username from the prepared statment to the actual value and specify the datatype for this variable
        $query->bindValue(":password", $password, PDO::PARAM_STR); //bind the alias password from the prepared statment to the actual value and specify the datatype for this variable
        $execute = $query->execute(); //execute the query
        $stop = array_sum(explode(' ', round(microtime(true) * 1000))); //stop time to  calculate the time it takes to execute a query. the log time is logged for debugging process
        $totalMs = substr(($stop - $start), 0, 5); //total ms it took to execute the query
        $array = array(); //declare the return $array as an array
        if ($execute == TRUE) {//If query executes successfully return $return array $results
            $key_column = null; //format the retun array
            while ($obj = $query->fetch(PDO::FETCH_ASSOC)) {
                isset($obj[$key_column]) ? $array[$obj[$key_column]] = $obj : $array[] = $obj;
            }//log the how long it took to execute the query and the trace which procedure was executed
            Yii::log("Took $totalMs ms to fetch Login Details result set", "info", self::LOG_CAT);
            Yii::log("[login] " . '" ' . $procedure . '"', "trace", self::LOG_CAT);
            return $array;
        } else {
            $results = 'not execute';
            return $results;
        }
    }
}
之后,我在控制器中初始化sqlresource,如下所示

public function actionExampleControllerAction() {
        $sql = new SqlResource();
        $results = $sql->ExampleSqlResourceFunction();
        if (isset($results) && !empty($results)) {
            foreach ($results as $key => $value) {
                $array[$key] = array(
                    'type' => 'column',
                    'name' => $value["Department_Name"],
                    'value' => $value['Count'],
                );
            }
        }
        echo json_encode($array, JSON_NUMERIC_CHECK);
        Yii::app()->end();
    }

在Yii2应用程序中使用createCommand函数

$result = \Yii::$app->db->createCommand("exec login_access @username = :username, @password = :password") 
                  ->bindValue(':username' , $username)
                  ->bindValue(':password', $password)
                  ->execute();
要将db更改为另一个,只需创建另一个组件,如dbMS

      //Your MySql db
        'db'=>
            [
                'class' => 'yii\db\Connection',
                'dsn' => 'mysql:host=localhost;dbname=my_database',
                'username' => 'root',
                'password' => '',
                'charset' => 'utf8',
            ],
        //Your MS SQL db
        'dbMS'=>
            [
                'class' => 'yii\db\Connection',
                'dsn' => 'dblib:host=mssqlserver;dbname=my_database',
                'username' => 'sa',
                'password' => 'superpass',
                'charset' => 'utf8',
            ],
因此,现在您可以在运行时轻松、动态地将MySQL数据库更改为MSSQL dbMS

$result = \Yii::$app->dbMS->createCommand("exec login_access @username = :username, @password = :password") 
                  ->bindValue(':username' , $username)
                  ->bindValue(':password', $password)
                  ->execute();