CMssqlCommandBuilder

优质
小牛编辑
133浏览
2023-12-01
所有包 | 属性 | 方法
system.db.schema.mssql
继承class CMssqlCommandBuilder » CDbCommandBuilder » CComponent
版本$Id: CMssqlCommandBuilder.php 3515 2011-12-28 12:29:24Z mdomba $
源码framework/db/schema/mssql/CMssqlCommandBuilder.php
CMssqlCommandBuilder提供为MSSQL数据表创建查询语句的基本方法。

公共属性

隐藏继承属性

属性类型描述定义在
dbConnectionCDbConnectiondatabase connection.CDbCommandBuilder
schemaCDbSchemathe schema for this command builder.CDbCommandBuilder

公共方法

隐藏继承方法

方法描述定义在
__call()如果类中没有调的方法名,则调用这个方法。CComponent
__construct()CDbCommandBuilder
__get()返回一个属性值、一个事件处理程序列表或一个行为名称。CComponent
__isset()检查一个属性是否为null。CComponent
__set()设置一个组件的属性值。CComponent
__unset()设置一个组件的属性为null。CComponent
applyCondition()Alters the SQL to apply WHERE clause.CDbCommandBuilder
applyGroup()Alters the SQL to apply GROUP BY.CDbCommandBuilder
applyHaving()Alters the SQL to apply HAVING.CDbCommandBuilder
applyJoin()Alters the SQL to apply JOIN clause.CDbCommandBuilder
applyLimit()This is a port from Prado Framework.CMssqlCommandBuilder
applyOrder()Alters the SQL to apply ORDER BY.CDbCommandBuilder
asa()返回这个名字的行为对象。CComponent
attachBehavior()附加一个行为到组件。CComponent
attachBehaviors()附加一个行为列表到组件。CComponent
attachEventHandler()为事件附加一个事件处理程序。CComponent
bindValues()Binds parameter values for an SQL command.CDbCommandBuilder
canGetProperty()确定属性是否可读。CComponent
canSetProperty()确定属性是否可写。CComponent
createColumnCriteria()Creates a query criteria with the specified column values.CDbCommandBuilder
createCountCommand()为一个表创建COUNT(*)语句。CMssqlCommandBuilder
createCriteria()Creates a query criteria.CDbCommandBuilder
createDeleteCommand()创建DELETE语句。CMssqlCommandBuilder
createFindCommand()为一个表创建SELECT语句。CMssqlCommandBuilder
createInCondition()Generates the expression for selecting rows of specified primary key values.CDbCommandBuilder
createInsertCommand()Creates an INSERT command.CDbCommandBuilder
createPkCondition()Generates the expression for selecting rows of specified primary key values.CDbCommandBuilder
createPkCriteria()Creates a query criteria with the specified primary key.CDbCommandBuilder
createSearchCondition()Generates the expression for searching the specified keywords within a list of columns.CDbCommandBuilder
createSqlCommand()Creates a command based on a given SQL statement.CDbCommandBuilder
createUpdateCommand()创建UPDATE语句。CMssqlCommandBuilder
createUpdateCounterCommand()创建递增或递减特定列的UPDATE语句。CMssqlCommandBuilder
detachBehavior()从组件中分离一个行为。CComponent
detachBehaviors()从组件中分离所有行为。CComponent
detachEventHandler()分离一个存在的事件处理程序。CComponent
disableBehavior()禁用一个附加行为。CComponent
disableBehaviors()禁用组件附加的所有行为。CComponent
enableBehavior()启用一个附加行为。CComponent
enableBehaviors()启用组件附加的所有行为。CComponent
evaluateExpression()计算一个PHP表达式,或根据组件上下文执行回调。CComponent
getDbConnection()返回database connection.CDbCommandBuilder
getEventHandlers()返回一个事件的附加处理程序列表。CComponent
getLastInsertID()Returns the last insertion ID for the specified table.CDbCommandBuilder
getSchema()返回the schema for this command builder.CDbCommandBuilder
hasEvent()确定一个事件是否定义。CComponent
hasEventHandler()检查事件是否有附加的处理程序。CComponent
hasProperty()确定属性是否被定义。CComponent
raiseEvent()发起一个事件。CComponent

受保护方法

隐藏继承方法

方法描述定义在
checkCriteria()检查使用offset或limit的查询条件是否有order by子句。CMssqlCommandBuilder
createCompositeInCondition()生成根据指定符合键值选择行的表达式。CMssqlCommandBuilder
ensureTable()Checks if the parameter is a valid table schema.CDbCommandBuilder
findOrdering()基于简化语法:http://msdn2.microsoft.com/en-us/library/aa259187(SQL.80).aspxCMssqlCommandBuilder
joinOrdering()CMssqlCommandBuilder
reverseDirection()CMssqlCommandBuilder
rewriteLimitOffsetSql()为MSSQL数据库重写SQL以应用$limit > 0和$offset > 0。CMssqlCommandBuilder

方法详细

applyLimit() 方法
public string applyLimit(string $sql, integer $limit, integer $offset)
$sqlstringSQL查询字符串
$limitinteger最大行数,若为-1则忽略limit。
$offsetinteger行偏移,若为-1则忽略offset。
{return}string带有limit和offset的SQL。
源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#179 (显示) publicfunctionapplyLimit($sql,$limit,$offset)
{
$limit=$limit!==null?intval($limit):-1;
$offset=$offset!==null?intval($offset):-1;
if($limit>0&&$offset<=0)//justlimit
$sql=preg_replace('/^([s(])*SELECT(DISTINCT)?(?!s*TOPs*()/i',"\1SELECT\2TOP$limit",$sql);
elseif($limit>0&&$offset>0)
$sql=$this->rewriteLimitOffsetSql($sql,$limit,$offset);
return$sql;
}

This is a port from Prado Framework.

重写父类的实现。改变SQL以应用$limit和$offset。 应用带有offset的limit是根据SQL语句结构的 许多假设通过动态修改SQL实现的。 根据下面地址的附注完成修改: http://troels.arvin.dk/db/rdbms/#select-limit-offset

SELECT * FROM ( SELECT TOP n * FROM ( SELECT TOP z columns -- (z=n+skip) FROM tablename ORDER BY key ASC ) AS FOO ORDER BY key DESC -- ('FOO' may be anything) ) AS BAR ORDER BY key ASC -- ('BAR' may be anything)

Regular expressions are used to alter the SQL query. The resulting SQL query may be malformed for complex queries. The following restrictions apply

  • In particular, commas should NOT be used as part of the ordering expression or identifier. Commas must only be used for separating the ordering clauses.
  • In the ORDER BY clause, the column name should NOT be be qualified with a table name or view name. Alias the column names or use column index.
  • No clauses should follow the ORDER BY clause, e.g. no COMPUTE or FOR clauses.
  • checkCriteria() 方法
    protected CDbCrireria checkCriteria(CMssqlTableSchema $table, CDbCriteria $criteria)
    $tableCMssqlTableSchema表schema
    $criteriaCDbCriteria查询条件
    {return}CDbCrireria修改后的查询条件
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#309 (显示) protectedfunctioncheckCriteria($table,$criteria)
    {
    if($criteria->offset>0&&$criteria->order==='')
    {
    $criteria->order=is_array($table->primaryKey)?implode(',',$table->primaryKey):$table->primaryKey;
    }
    return$criteria;
    }

    检查使用offset或limit的查询条件是否有order by子句。 重写父类的实现以检查带有offset的查询中order by子句是否已指定。 若未指定order by子句,则按主键排序。

    createCompositeInCondition() 方法
    protected string createCompositeInCondition(CDbTableSchema $table, array $values, string $prefix)
    $tableCDbTableSchema表schema
    $valuesarray要选择的主键值列表
    $prefixstring列前缀(以.结束)
    {return}string选择的表达式。
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#325 (显示) protectedfunctioncreateCompositeInCondition($table,$values,$prefix)
    {
    $vs=array();
    foreach($valuesas$value)
    {
    $c=array();
    foreach($valueas$k=>$v)
    $c[]=$prefix.$table->columns[$k]->rawName.'='.$v;
    $vs[]='('.implode('AND',$c).')';
    }
    return'('.implode('OR',$vs).')';
    }

    生成根据指定符合键值选择行的表达式。

    createCountCommand() 方法
    public CDbCommand createCountCommand(CDbTableSchema $table, CDbCriteria $criteria, string $alias='t')
    $tableCDbTableSchema表元数据。
    $criteriaCDbCriteria查询条件。
    $aliasstring主表的别名。默认为‘t’。
    {return}CDbCommand查询语句。
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#32 (显示) publicfunctioncreateCountCommand($table,$criteria,$alias='t')
    {
    $criteria->order='';
    returnparent::createCountCommand($table,$criteria,$alias);
    }

    为一个表创建COUNT(*)语句。 重写父类的实现以移除条件里的order子句(如果它存在)。

    createDeleteCommand() 方法
    public CDbCommand createDeleteCommand(CDbTableSchema $table, CDbCriteria $criteria)
    $tableCDbTableSchema表元数据
    $criteriaCDbCriteria查询条件
    {return}CDbCommanddelete语句。
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#115 (显示) publicfunctioncreateDeleteCommand($table,$criteria)
    {
    $criteria=$this->checkCriteria($table,$criteria);
    returnparent::createDeleteCommand($table,$criteria);
    }

    创建DELETE语句。 重写父类的实现以检查带有offset的查询中order by子句是否已指定。

    createFindCommand() 方法
    public CDbCommand createFindCommand(CDbTableSchema $table, CDbCriteria $criteria, string $alias='t')
    $tableCDbTableSchema表元数据。
    $criteriaCDbCriteria查询条件。
    $aliasstring主表的别名。默认为‘t’。
    {return}CDbCommand查询语句。
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#46 (显示) publicfunctioncreateFindCommand($table,$criteria,$alias='t')
    {
    $criteria=$this->checkCriteria($table,$criteria);
    returnparent::createFindCommand($table,$criteria,$alias);

    }

    为一个表创建SELECT语句。 重写父类的实现以检查带有offset的查询中order by子句是否已指定。

    createUpdateCommand() 方法
    public CDbCommand createUpdateCommand(CDbTableSchema $table, array $data, CDbCriteria $criteria)
    $tableCDbTableSchema表元数据。
    $dataarray要更新的列(名=>值)
    $criteriaCDbCriteria查询条件
    {return}CDbCommandupdate语句。
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#61 (显示) publicfunctioncreateUpdateCommand($table,$data,$criteria)
    {
    $criteria=$this->checkCriteria($table,$criteria);
    $fields=array();
    $values=array();
    $bindByPosition=isset($criteria->params[0]);
    $i=0;
    foreach($dataas$name=>$value)
    {
    if(($column=$table->getColumn($name))!==null)
    {
    if($table->sequenceName!==null&&$column->isPrimaryKey===true)continue;
    if($column->dbType==='timestamp')continue;
    if($valueinstanceofCDbExpression)
    {
    $fields[]=$column->rawName.'='.$value->expression;
    foreach($value->paramsas$n=>$v)
    $values[$n]=$v;
    }
    elseif($bindByPosition)
    {
    $fields[]=$column->rawName.'=?';
    $values[]=$column->typecast($value);
    }
    else
    {
    $fields[]=$column->rawName.'='.self::PARAM_PREFIX.$i;
    $values[self::PARAM_PREFIX.$i]=$column->typecast($value);
    $i++;
    }
    }
    }
    if($fields===array())
    thrownewCDbException(Yii::t('yii','Nocolumnsarebeingupdatedfortable"{table}".',
    array('{table}'=>$table->name)));
    $sql="UPDATE{$table->rawName}SET".implode(',',$fields);
    $sql=$this->applyJoin($sql,$criteria->join);
    $sql=$this->applyCondition($sql,$criteria->condition);
    $sql=$this->applyOrder($sql,$criteria->order);
    $sql=$this->applyLimit($sql,$criteria->limit,$criteria->offset);

    $command=$this->getDbConnection()->createCommand($sql);
    $this->bindValues($command,array_merge($values,$criteria->params));

    return$command;
    }

    创建UPDATE语句。 重写父类的实现因为MSSQL不希望更新标识列。

    createUpdateCounterCommand() 方法
    public CDbCommand createUpdateCounterCommand(CDbTableSchema $table, CDbCriteria $counters, array $criteria)
    $tableCDbTableSchema表元数据
    $countersCDbCriteria查询条件
    $criteriaarray要更新的计数器(列名为索引的递增或递减计数器)。
    {return}CDbCommandupdate语句。
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#130 (显示) publicfunctioncreateUpdateCounterCommand($table,$counters,$criteria)
    {
    $criteria=$this->checkCriteria($table,$criteria);
    returnparent::createUpdateCounterCommand($table,$counters,$criteria);
    }

    创建递增或递减特定列的UPDATE语句。 重写父类的实现以检查带有offset的查询中order by子句是否已指定。

    findOrdering() 方法
    protected array findOrdering(string $sql)
    $sqlstring$sql
    {return}array排序表达式作为键及排序方向作为值。
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#219 (显示) protectedfunctionfindOrdering($sql)
    {
    if(!preg_match('/ORDERBY/i',$sql))
    returnarray();
    $matches=array();
    $ordering=array();
    preg_match_all('/(ORDERBY)[s"[](.*)(ASC|DESC)?(?:[s"[]|$|COMPUTE|FOR)/i',$sql,$matches);
    if(count($matches)>1&&count($matches[2])>0)
    {
    $parts=explode(',',$matches[2][0]);
    foreach($partsas$part)
    {
    $subs=array();
    if(preg_match_all('/(.*)[s"]](ASC|DESC)$/i',trim($part),$subs))
    {
    if(count($subs)>1&&count($subs[2])>0)
    {
    $name='';
    foreach(explode('.',$subs[1][0])as$p)
    {
    if($name!=='')
    $name.='.';
    $name.='['.trim($p,'[]').']';
    }
    $ordering[$name]=$subs[2][0];
    }
    //elsewhat?
    }
    else
    $ordering[trim($part)]='ASC';
    }
    }

    //replacingcolumnnameswiththeiraliasnames
    foreach($orderingas$name=>$direction)
    {
    $matches=array();
    $pattern='/s+'.str_replace(array('[',']'),array('[',']'),$name).'s+ASs+([[^]]+])/i';
    preg_match($pattern,$sql,$matches);
    if(isset($matches[1]))
    {
    $ordering[$matches[1]]=$ordering[$name];
    unset($ordering[$name]);
    }
    }

    return$ordering;
    }

    基于简化语法:http://msdn2.microsoft.com/en-us/library/aa259187(SQL.80).aspx

    joinOrdering() 方法
    protected string joinOrdering(array $orders, string $newPrefix)
    $ordersarray从findOrdering获得的order信息
    $newPrefixstring加在排序列的新表前缀。
    {return}string连接后的order表达式。
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#275 (显示) protectedfunctionjoinOrdering($orders,$newPrefix)
    {
    if(count($orders)>0)
    {
    $str=array();
    foreach($ordersas$column=>$direction)
    $str[]=$column.''.$direction;
    $orderBy='ORDERBY'.implode(',',$str);
    returnpreg_replace('/s+[[^]]+].([[^]]+])/i',''.$newPrefix.'.1',$orderBy);
    }
    }
    reverseDirection() 方法
    protected array reverseDirection(array $orders)
    $ordersarray原始order信息
    {return}array反转方向的order信息。
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#293 (显示) protectedfunctionreverseDirection($orders)
    {
    foreach($ordersas$column=>$direction)
    $orders[$column]=strtolower(trim($direction))==='desc'?'ASC':'DESC';
    return$orders;
    }
    rewriteLimitOffsetSql() 方法
    protected sql rewriteLimitOffsetSql(string $sql, integer $limit, integer $offset)
    $sqlstringSQL查询
    $limitinteger$limit > 0
    $offsetinteger$offset > 0
    {return}sql应用limit和offset的修改后SQL查询
    源码: framework/db/schema/mssql/CMssqlCommandBuilder.php#200 (显示) protectedfunctionrewriteLimitOffsetSql($sql,$limit,$offset)
    {
    $fetch=$limit+$offset;
    $sql=preg_replace('/^([s(])*SELECT(DISTINCT)?(?!s*TOPs*()/i',"\1SELECT\2TOP$fetch",$sql);
    $ordering=$this->findOrdering($sql);
    $orginalOrdering=$this->joinOrdering($ordering,'[__outer__]');
    $reverseOrdering=$this->joinOrdering($this->reverseDirection($ordering),'[__inner__]');
    $sql="SELECT*FROM(SELECTTOP{$limit}*FROM($sql)as[__inner__]{$reverseOrdering})as[__outer__]{$orginalOrdering}";
    return$sql;
    }

    为MSSQL数据库重写SQL以应用$limit > 0和$offset > 0。 参见http://troels.arvin.dk/db/rdbms/#select-limit-offset