Sqlsrv.class.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 protected
  101. * @param string $key
  102. * @return string
  103. */
  104. protected function parseKey($key)
  105. {
  106. $key = trim($key);
  107. if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
  108. $key = '[' . $key . ']';
  109. }
  110. return $key;
  111. }
  112. /**
  113. * limit
  114. * @access public
  115. * @param mixed $limit
  116. * @return string
  117. */
  118. public function parseLimit($limit)
  119. {
  120. if (empty($limit)) {
  121. return '';
  122. }
  123. $limit = explode(',', $limit);
  124. if (count($limit) > 1) {
  125. $limitStr = '(T1.ROW_NUMBER BETWEEN ' . $limit[0] . ' + 1 AND ' . $limit[0] . ' + ' . $limit[1] . ')';
  126. } else {
  127. $limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND ' . $limit[0] . ")";
  128. }
  129. return 'WHERE ' . $limitStr;
  130. }
  131. /**
  132. * 更新记录
  133. * @access public
  134. * @param mixed $data 数据
  135. * @param array $options 表达式
  136. * @return false | integer
  137. */
  138. public function update($data, $options)
  139. {
  140. $this->model = $options['model'];
  141. $this->parseBind(!empty($options['bind']) ? $options['bind'] : array());
  142. $sql = 'UPDATE '
  143. . $this->parseTable($options['table'])
  144. . $this->parseSet($data)
  145. . $this->parseWhere(!empty($options['where']) ? $options['where'] : '')
  146. . $this->parseLock(isset($options['lock']) ? $options['lock'] : false)
  147. . $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
  148. return $this->execute($sql, !empty($options['fetch_sql']) ? true : false);
  149. }
  150. /**
  151. * 删除记录
  152. * @access public
  153. * @param array $options 表达式
  154. * @return false | integer
  155. */
  156. public function delete($options = array())
  157. {
  158. $this->model = $options['model'];
  159. $this->parseBind(!empty($options['bind']) ? $options['bind'] : array());
  160. $sql = 'DELETE FROM '
  161. . $this->parseTable($options['table'])
  162. . $this->parseWhere(!empty($options['where']) ? $options['where'] : '')
  163. . $this->parseLock(isset($options['lock']) ? $options['lock'] : false)
  164. . $this->parseComment(!empty($options['comment']) ? $options['comment'] : '');
  165. return $this->execute($sql, !empty($options['fetch_sql']) ? true : false);
  166. }
  167. }