Sqlsrv.class.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace Think\Db\Driver;
  12. use PDO;
  13. use Think\Db\Driver;
  14. /**
  15. * Sqlsrv数据库驱动
  16. */
  17. class Sqlsrv extends Driver
  18. {
  19. protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING% %UNION%) AS thinkphp) AS T1 %LIMIT%%COMMENT%';
  20. // PDO连接参数
  21. protected $options = array(
  22. PDO::ATTR_CASE => PDO::CASE_LOWER,
  23. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  24. PDO::ATTR_STRINGIFY_FETCHES => false,
  25. PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
  26. );
  27. /**
  28. * 解析pdo连接的dsn信息
  29. * @access public
  30. * @param array $config 连接信息
  31. * @return string
  32. */
  33. protected function parseDsn($config)
  34. {
  35. $dsn = 'sqlsrv:Database=' . $config['database'] . ';Server=' . $config['hostname'];
  36. if (!empty($config['hostport'])) {
  37. $dsn .= ',' . $config['hostport'];
  38. }
  39. return $dsn;
  40. }
  41. /**
  42. * 取得数据表的字段信息
  43. * @access public
  44. * @return array
  45. */
  46. public function getFields($tableName)
  47. {
  48. list($tableName) = explode(' ', $tableName);
  49. $result = $this->query("SELECT column_name, data_type, column_default, is_nullable
  50. FROM information_schema.tables AS t
  51. JOIN information_schema.columns AS c
  52. ON t.table_catalog = c.table_catalog
  53. AND t.table_schema = c.table_schema
  54. AND t.table_name = c.table_name
  55. WHERE t.table_name = '$tableName'");
  56. $info = array();
  57. if ($result) {
  58. foreach ($result as $key => $val) {
  59. $info[$val['column_name']] = array(
  60. 'name' => $val['column_name'],
  61. 'type' => $val['data_type'],
  62. 'notnull' => (bool) ('' === $val['is_nullable']), // not null is empty, null is yes
  63. 'default' => $val['column_default'],
  64. 'primary' => false,
  65. 'autoinc' => false,
  66. );
  67. }
  68. }
  69. return $info;
  70. }
  71. /**
  72. * 取得数据表的字段信息
  73. * @access public
  74. * @return array
  75. */
  76. public function getTables($dbName = '')
  77. {
  78. $result = $this->query("SELECT TABLE_NAME
  79. FROM INFORMATION_SCHEMA.TABLES
  80. WHERE TABLE_TYPE = 'BASE TABLE'
  81. ");
  82. $info = array();
  83. foreach ($result as $key => $val) {
  84. $info[$key] = current($val);
  85. }
  86. return $info;
  87. }
  88. /**
  89. * order分析
  90. * @access protected
  91. * @param mixed $order
  92. * @return string
  93. */
  94. protected function parseOrder($order)
  95. {
  96. return !empty($order) ? ' ORDER BY ' . $order : ' ORDER BY rand()';
  97. }
  98. /**
  99. * 字段和表名处理
  100. * @access public
  101. * @param string $key
  102. * @param bool $strict
  103. * @return string
  104. */
  105. public function parseKey($key, $strict = false)
  106. {
  107. $key = trim($key);
  108. if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
  109. E('not support data:' . $key);
  110. }
  111. if ($strict || (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) {
  112. $key = '[' . $key . ']';
  113. }
  114. return $key;
  115. }
  116. /**
  117. * limit
  118. * @access public
  119. * @param mixed $limit
  120. * @return string
  121. */
  122. public function parseLimit($limit)
  123. {
  124. if (empty($limit)) {
  125. return '';
  126. }
  127. $limit = explode(',', $limit);
  128. if (count($limit) > 1) {
  129. $limitStr = '(T1.ROW_NUMBER BETWEEN ' . $limit[0] . ' + 1 AND ' . $limit[0] . ' + ' . $limit[1] . ')';
  130. } else {
  131. $limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND ' . $limit[0] . ")";
  132. }
  133. return 'WHERE ' . $limitStr;
  134. }
  135. /**
  136. * 更新记录
  137. * @access public
  138. * @param mixed $data 数据
  139. * @param array $options 表达式
  140. * @return false | integer
  141. */
  142. public function update($data, $options)
  143. {
  144. $this->model = $options['model'];
  145. $this->parseBind(!empty($options['bind']) ? $options['bind'] : array());
  146. $sql = 'UPDATE '
  147. . $this->parseTable($options['table'])
  148. . $this->parseSet($data)
  149. . $this->parseWhere(!empty($options['where']) ? $options['where'] : '')
  150. . $this->parseLock(isset($options['lock']) ? $options['lock'] : false)
  151. . $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
  152. return $this->execute($sql, !empty($options['fetch_sql']) ? true : false);
  153. }
  154. /**
  155. * 删除记录
  156. * @access public
  157. * @param array $options 表达式
  158. * @return false | integer
  159. */
  160. public function delete($options = array())
  161. {
  162. $this->model = $options['model'];
  163. $this->parseBind(!empty($options['bind']) ? $options['bind'] : array());
  164. $sql = 'DELETE FROM '
  165. . $this->parseTable($options['table'])
  166. . $this->parseWhere(!empty($options['where']) ? $options['where'] : '')
  167. . $this->parseLock(isset($options['lock']) ? $options['lock'] : false)
  168. . $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
  169. return $this->execute($sql, !empty($options['fetch_sql']) ? true : false);
  170. }
  171. }