00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 if (!defined('ADODB_DIR')) die();
00017
00018 if (!defined('_ADODB_ODBC_LAYER')) {
00019 include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
00020 }
00021
00022
00023 class ADODB_odbc_mssql extends ADODB_odbc {
00024 var $databaseType = 'odbc_mssql';
00025 var $fmtDate = "'Y-m-d'";
00026 var $fmtTimeStamp = "'Y-m-d H:i:s'";
00027 var $_bindInputArray = true;
00028 var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE'))";
00029 var $metaColumnsSQL = "select c.name,t.name,c.length from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
00030 var $hasTop = 'top';
00031 var $sysDate = 'GetDate()';
00032 var $sysTimeStamp = 'GetDate()';
00033 var $leftOuter = '*=';
00034 var $rightOuter = '=*';
00035 var $substr = 'substring';
00036 var $length = 'len';
00037 var $ansiOuter = true;
00038 var $identitySQL = 'select @@IDENTITY';
00039 var $hasInsertID = true;
00040 var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL OFF'; # When SET CONCAT_NULL_YIELDS_NULL is ON,
00041 # concatenating a null value with a string yields a NULL result
00042
00043 function ADODB_odbc_mssql()
00044 {
00045 $this->ADODB_odbc();
00046
00047 }
00048
00049
00050 function ServerInfo()
00051 {
00052 global $ADODB_FETCH_MODE;
00053 $save = $ADODB_FETCH_MODE;
00054 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00055 $row = $this->GetRow("execute sp_server_info 2");
00056 $ADODB_FETCH_MODE = $save;
00057 if (!is_array($row)) return false;
00058 $arr['description'] = $row[2];
00059 $arr['version'] = ADOConnection::_findvers($arr['description']);
00060 return $arr;
00061 }
00062
00063 function IfNull( $field, $ifNull )
00064 {
00065 return " ISNULL($field, $ifNull) ";
00066 }
00067
00068 function _insertid()
00069 {
00070
00071
00072
00073
00074
00075 return $this->GetOne($this->identitySQL);
00076 }
00077
00078
00079 function MetaForeignKeys($table, $owner=false, $upper=false)
00080 {
00081 global $ADODB_FETCH_MODE;
00082
00083 $save = $ADODB_FETCH_MODE;
00084 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00085 $table = $this->qstr(strtoupper($table));
00086
00087 $sql =
00088 "select object_name(constid) as constraint_name,
00089 col_name(fkeyid, fkey) as column_name,
00090 object_name(rkeyid) as referenced_table_name,
00091 col_name(rkeyid, rkey) as referenced_column_name
00092 from sysforeignkeys
00093 where upper(object_name(fkeyid)) = $table
00094 order by constraint_name, referenced_table_name, keyno";
00095
00096 $constraints =& $this->GetArray($sql);
00097
00098 $ADODB_FETCH_MODE = $save;
00099
00100 $arr = false;
00101 foreach($constraints as $constr) {
00102
00103 $arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
00104 }
00105 if (!$arr) return false;
00106
00107 $arr2 = false;
00108
00109 foreach($arr as $k => $v) {
00110 foreach($v as $a => $b) {
00111 if ($upper) $a = strtoupper($a);
00112 $arr2[$a] = $b;
00113 }
00114 }
00115 return $arr2;
00116 }
00117
00118 function &MetaTables($ttype=false,$showSchema=false,$mask=false)
00119 {
00120 if ($mask) {$this->debug=1;
00121 $save = $this->metaTablesSQL;
00122 $mask = $this->qstr($mask);
00123 $this->metaTablesSQL .= " AND name like $mask";
00124 }
00125 $ret =& ADOConnection::MetaTables($ttype,$showSchema);
00126
00127 if ($mask) {
00128 $this->metaTablesSQL = $save;
00129 }
00130 return $ret;
00131 }
00132
00133 function &MetaColumns($table)
00134 {
00135 $arr = ADOConnection::MetaColumns($table);
00136 return $arr;
00137 }
00138
00139
00140 function &MetaIndexes($table,$primary=false)
00141 {
00142 $table = $this->qstr($table);
00143
00144 $sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
00145 CASE WHEN I.indid BETWEEN 1 AND 254 AND (I.status & 2048 = 2048 OR I.Status = 16402 AND O.XType = 'V') THEN 1 ELSE 0 END AS IsPK,
00146 CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
00147 FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
00148 INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
00149 INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
00150 WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND O.Name LIKE $table
00151 ORDER BY O.name, I.Name, K.keyno";
00152
00153 global $ADODB_FETCH_MODE;
00154 $save = $ADODB_FETCH_MODE;
00155 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00156 if ($this->fetchMode !== FALSE) {
00157 $savem = $this->SetFetchMode(FALSE);
00158 }
00159
00160 $rs = $this->Execute($sql);
00161 if (isset($savem)) {
00162 $this->SetFetchMode($savem);
00163 }
00164 $ADODB_FETCH_MODE = $save;
00165
00166 if (!is_object($rs)) {
00167 return FALSE;
00168 }
00169
00170 $indexes = array();
00171 while ($row = $rs->FetchRow()) {
00172 if (!$primary && $row[5]) continue;
00173
00174 $indexes[$row[0]]['unique'] = $row[6];
00175 $indexes[$row[0]]['columns'][] = $row[1];
00176 }
00177 return $indexes;
00178 }
00179
00180 function _query($sql,$inputarr)
00181 {
00182 if (is_string($sql)) $sql = str_replace('||','+',$sql);
00183 return ADODB_odbc::_query($sql,$inputarr);
00184 }
00185
00186 function SetTransactionMode( $transaction_mode )
00187 {
00188 $this->_transmode = $transaction_mode;
00189 if (empty($transaction_mode)) {
00190 $this->Execute('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
00191 return;
00192 }
00193 if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
00194 $this->Execute("SET TRANSACTION ".$transaction_mode);
00195 }
00196
00197
00198
00199 function &MetaPrimaryKeys($table)
00200 {
00201 global $ADODB_FETCH_MODE;
00202
00203 $schema = '';
00204 $this->_findschema($table,$schema);
00205
00206 if ($schema) $schema = "and k.table_catalog like '$schema%'";
00207
00208 $sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
00209 information_schema.table_constraints tc
00210 where tc.constraint_name = k.constraint_name and tc.constraint_type =
00211 'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
00212
00213 $savem = $ADODB_FETCH_MODE;
00214 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
00215 $a = $this->GetCol($sql);
00216 $ADODB_FETCH_MODE = $savem;
00217
00218 if ($a && sizeof($a)>0) return $a;
00219 $false = false;
00220 return $false;
00221 }
00222
00223 function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
00224 {
00225 if ($nrows > 0 && $offset <= 0) {
00226 $sql = preg_replace(
00227 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
00228 $rs =& $this->Execute($sql,$inputarr);
00229 } else
00230 $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
00231
00232 return $rs;
00233 }
00234
00235
00236 function SQLDate($fmt, $col=false)
00237 {
00238 if (!$col) $col = $this->sysTimeStamp;
00239 $s = '';
00240
00241 $len = strlen($fmt);
00242 for ($i=0; $i < $len; $i++) {
00243 if ($s) $s .= '+';
00244 $ch = $fmt[$i];
00245 switch($ch) {
00246 case 'Y':
00247 case 'y':
00248 $s .= "datename(yyyy,$col)";
00249 break;
00250 case 'M':
00251 $s .= "convert(char(3),$col,0)";
00252 break;
00253 case 'm':
00254 $s .= "replace(str(month($col),2),' ','0')";
00255 break;
00256 case 'Q':
00257 case 'q':
00258 $s .= "datename(quarter,$col)";
00259 break;
00260 case 'D':
00261 case 'd':
00262 $s .= "replace(str(day($col),2),' ','0')";
00263 break;
00264 case 'h':
00265 $s .= "substring(convert(char(14),$col,0),13,2)";
00266 break;
00267
00268 case 'H':
00269 $s .= "replace(str(datepart(hh,$col),2),' ','0')";
00270 break;
00271
00272 case 'i':
00273 $s .= "replace(str(datepart(mi,$col),2),' ','0')";
00274 break;
00275 case 's':
00276 $s .= "replace(str(datepart(ss,$col),2),' ','0')";
00277 break;
00278 case 'a':
00279 case 'A':
00280 $s .= "substring(convert(char(19),$col,0),18,2)";
00281 break;
00282
00283 default:
00284 if ($ch == '\\') {
00285 $i++;
00286 $ch = substr($fmt,$i,1);
00287 }
00288 $s .= $this->qstr($ch);
00289 break;
00290 }
00291 }
00292 return $s;
00293 }
00294
00295 }
00296
00297 class ADORecordSet_odbc_mssql extends ADORecordSet_odbc {
00298
00299 var $databaseType = 'odbc_mssql';
00300
00301 function ADORecordSet_odbc_mssql($id,$mode=false)
00302 {
00303 return $this->ADORecordSet_odbc($id,$mode);
00304 }
00305 }
00306 ?>