| 36 | kaklik | 1 | <?php
 | 
        
           |  |  | 2 | /* 
 | 
        
           |  |  | 3 | V4.80 8 Mar 2006  (c) 2000-2006 John Lim (jlim@natsoft.com.my). All rights reserved.
 | 
        
           |  |  | 4 |   Released under both BSD license and Lesser GPL library license. 
 | 
        
           |  |  | 5 |   Whenever there is any discrepancy between the two licenses, 
 | 
        
           |  |  | 6 |   the BSD license will take precedence. 
 | 
        
           |  |  | 7 | Set tabs to 4 for best viewing.
 | 
        
           |  |  | 8 |   | 
        
           |  |  | 9 |   Latest version is available at http://adodb.sourceforge.net
 | 
        
           |  |  | 10 |   | 
        
           |  |  | 11 |   Native mssql driver. Requires mssql client. Works on Windows. 
 | 
        
           |  |  | 12 |   To configure for Unix, see 
 | 
        
           |  |  | 13 |    	http://phpbuilder.com/columns/alberto20000919.php3
 | 
        
           |  |  | 14 |   | 
        
           |  |  | 15 | */
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 | // security - hide paths
 | 
        
           |  |  | 18 | if (!defined('ADODB_DIR')) die();
 | 
        
           |  |  | 19 |   | 
        
           |  |  | 20 | //----------------------------------------------------------------
 | 
        
           |  |  | 21 | // MSSQL returns dates with the format Oct 13 2002 or 13 Oct 2002
 | 
        
           |  |  | 22 | // and this causes tons of problems because localized versions of 
 | 
        
           |  |  | 23 | // MSSQL will return the dates in dmy or  mdy order; and also the 
 | 
        
           |  |  | 24 | // month strings depends on what language has been configured. The 
 | 
        
           |  |  | 25 | // following two variables allow you to control the localization
 | 
        
           |  |  | 26 | // settings - Ugh.
 | 
        
           |  |  | 27 | //
 | 
        
           |  |  | 28 | // MORE LOCALIZATION INFO
 | 
        
           |  |  | 29 | // ----------------------
 | 
        
           |  |  | 30 | // To configure datetime, look for and modify sqlcommn.loc, 
 | 
        
           |  |  | 31 | //  	typically found in c:\mssql\install
 | 
        
           |  |  | 32 | // Also read :
 | 
        
           |  |  | 33 | //	 http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
 | 
        
           |  |  | 34 | // Alternatively use:
 | 
        
           |  |  | 35 | // 	   CONVERT(char(12),datecol,120)
 | 
        
           |  |  | 36 | //----------------------------------------------------------------
 | 
        
           |  |  | 37 |   | 
        
           |  |  | 38 |   | 
        
           |  |  | 39 | // has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
 | 
        
           |  |  | 40 | if (ADODB_PHPVER >= 0x4300) {
 | 
        
           |  |  | 41 | // docs say 4.2.0, but testing shows only since 4.3.0 does it work!
 | 
        
           |  |  | 42 | 	ini_set('mssql.datetimeconvert',0); 
 | 
        
           |  |  | 43 | } else {
 | 
        
           |  |  | 44 | global $ADODB_mssql_mths;		// array, months must be upper-case
 | 
        
           |  |  | 45 |   | 
        
           |  |  | 46 |   | 
        
           |  |  | 47 | 	$ADODB_mssql_date_order = 'mdy'; 
 | 
        
           |  |  | 48 | 	$ADODB_mssql_mths = array(
 | 
        
           |  |  | 49 | 		'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
 | 
        
           |  |  | 50 | 		'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
 | 
        
           |  |  | 51 | }
 | 
        
           |  |  | 52 |   | 
        
           |  |  | 53 | //---------------------------------------------------------------------------
 | 
        
           |  |  | 54 | // Call this to autoset $ADODB_mssql_date_order at the beginning of your code,
 | 
        
           |  |  | 55 | // just after you connect to the database. Supports mdy and dmy only.
 | 
        
           |  |  | 56 | // Not required for PHP 4.2.0 and above.
 | 
        
           |  |  | 57 | function AutoDetect_MSSQL_Date_Order($conn)
 | 
        
           |  |  | 58 | {
 | 
        
           |  |  | 59 | global $ADODB_mssql_date_order;
 | 
        
           |  |  | 60 | 	$adate = $conn->GetOne('select getdate()');
 | 
        
           |  |  | 61 | 	if ($adate) {
 | 
        
           |  |  | 62 | 		$anum = (int) $adate;
 | 
        
           |  |  | 63 | 		if ($anum > 0) {
 | 
        
           |  |  | 64 | 			if ($anum > 31) {
 | 
        
           |  |  | 65 | 				//ADOConnection::outp( "MSSQL: YYYY-MM-DD date format not supported currently");
 | 
        
           |  |  | 66 | 			} else
 | 
        
           |  |  | 67 | 				$ADODB_mssql_date_order = 'dmy';
 | 
        
           |  |  | 68 | 		} else
 | 
        
           |  |  | 69 | 			$ADODB_mssql_date_order = 'mdy';
 | 
        
           |  |  | 70 | 	}
 | 
        
           |  |  | 71 | }
 | 
        
           |  |  | 72 |   | 
        
           |  |  | 73 | class ADODB_mssql extends ADOConnection {
 | 
        
           |  |  | 74 | 	var $databaseType = "mssql";	
 | 
        
           |  |  | 75 | 	var $dataProvider = "mssql";
 | 
        
           |  |  | 76 | 	var $replaceQuote = "''"; // string to use to replace quotes
 | 
        
           |  |  | 77 | 	var $fmtDate = "'Y-m-d'";
 | 
        
           |  |  | 78 | 	var $fmtTimeStamp = "'Y-m-d H:i:s'";
 | 
        
           |  |  | 79 | 	var $hasInsertID = true;
 | 
        
           |  |  | 80 | 	var $substr = "substring";
 | 
        
           |  |  | 81 | 	var $length = 'len';
 | 
        
           |  |  | 82 | 	var $hasAffectedRows = true;
 | 
        
           |  |  | 83 | 	var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
 | 
        
           |  |  | 84 | 	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','dtproperties'))";
 | 
        
           |  |  | 85 | 	var $metaColumnsSQL = # xtype==61 is datetime
 | 
        
           |  |  | 86 | "select c.name,t.name,c.length,
 | 
        
           |  |  | 87 | 	(case when c.xusertype=61 then 0 else c.xprec end),
 | 
        
           |  |  | 88 | 	(case when c.xusertype=61 then 0 else c.xscale end) 
 | 
        
           |  |  | 89 | 	from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
 | 
        
           |  |  | 90 | 	var $hasTop = 'top';		// support mssql SELECT TOP 10 * FROM TABLE
 | 
        
           |  |  | 91 | 	var $hasGenID = true;
 | 
        
           |  |  | 92 | 	var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
 | 
        
           |  |  | 93 | 	var $sysTimeStamp = 'GetDate()';
 | 
        
           |  |  | 94 | 	var $_has_mssql_init;
 | 
        
           |  |  | 95 | 	var $maxParameterLen = 4000;
 | 
        
           |  |  | 96 | 	var $arrayClass = 'ADORecordSet_array_mssql';
 | 
        
           |  |  | 97 | 	var $uniqueSort = true;
 | 
        
           |  |  | 98 | 	var $leftOuter = '*=';
 | 
        
           |  |  | 99 | 	var $rightOuter = '=*';
 | 
        
           |  |  | 100 | 	var $ansiOuter = true; // for mssql7 or later
 | 
        
           |  |  | 101 | 	var $poorAffectedRows = true;
 | 
        
           |  |  | 102 | 	var $identitySQL = 'select @@IDENTITY'; // 'select SCOPE_IDENTITY'; # for mssql 2000
 | 
        
           |  |  | 103 | 	var $uniqueOrderBy = true;
 | 
        
           |  |  | 104 | 	var $_bindInputArray = true;
 | 
        
           |  |  | 105 |   | 
        
           |  |  | 106 | 	function ADODB_mssql() 
 | 
        
           |  |  | 107 | 	{		
 | 
        
           |  |  | 108 | 		$this->_has_mssql_init = (strnatcmp(PHP_VERSION,'4.1.0')>=0);
 | 
        
           |  |  | 109 | 	}
 | 
        
           |  |  | 110 |   | 
        
           |  |  | 111 | 	function ServerInfo()
 | 
        
           |  |  | 112 | 	{
 | 
        
           |  |  | 113 | 	global $ADODB_FETCH_MODE;
 | 
        
           |  |  | 114 |   | 
        
           |  |  | 115 | 		$stmt = $this->PrepareSP('sp_server_info');
 | 
        
           |  |  | 116 | 		$val = 2;
 | 
        
           |  |  | 117 | 		if ($this->fetchMode === false) {
 | 
        
           |  |  | 118 | 			$savem = $ADODB_FETCH_MODE;
 | 
        
           |  |  | 119 | 			$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 | 
        
           |  |  | 120 | 		} else 
 | 
        
           |  |  | 121 | 			$savem = $this->SetFetchMode(ADODB_FETCH_NUM);
 | 
        
           |  |  | 122 |   | 
        
           |  |  | 123 |   | 
        
           |  |  | 124 | 		$this->Parameter($stmt,$val,'attribute_id');
 | 
        
           |  |  | 125 | 		$row = $this->GetRow($stmt);
 | 
        
           |  |  | 126 |   | 
        
           |  |  | 127 | 		//$row = $this->GetRow("execute sp_server_info 2");
 | 
        
           |  |  | 128 |   | 
        
           |  |  | 129 |   | 
        
           |  |  | 130 | 		if ($this->fetchMode === false) {
 | 
        
           |  |  | 131 | 			$ADODB_FETCH_MODE = $savem;
 | 
        
           |  |  | 132 | 		} else
 | 
        
           |  |  | 133 | 			$this->SetFetchMode($savem);
 | 
        
           |  |  | 134 |   | 
        
           |  |  | 135 | 		$arr['description'] = $row[2];
 | 
        
           |  |  | 136 | 		$arr['version'] = ADOConnection::_findvers($arr['description']);
 | 
        
           |  |  | 137 | 		return $arr;
 | 
        
           |  |  | 138 | 	}
 | 
        
           |  |  | 139 |   | 
        
           |  |  | 140 | 	function IfNull( $field, $ifNull ) 
 | 
        
           |  |  | 141 | 	{
 | 
        
           |  |  | 142 | 		return " ISNULL($field, $ifNull) "; // if MS SQL Server
 | 
        
           |  |  | 143 | 	}
 | 
        
           |  |  | 144 |   | 
        
           |  |  | 145 | 	function _insertid()
 | 
        
           |  |  | 146 | 	{
 | 
        
           |  |  | 147 | 	// SCOPE_IDENTITY()
 | 
        
           |  |  | 148 | 	// Returns the last IDENTITY value inserted into an IDENTITY column in 
 | 
        
           |  |  | 149 | 	// the same scope. A scope is a module -- a stored procedure, trigger, 
 | 
        
           |  |  | 150 | 	// function, or batch. Thus, two statements are in the same scope if 
 | 
        
           |  |  | 151 | 	// they are in the same stored procedure, function, or batch.
 | 
        
           |  |  | 152 | 			return $this->GetOne($this->identitySQL);
 | 
        
           |  |  | 153 | 	}
 | 
        
           |  |  | 154 |   | 
        
           |  |  | 155 | 	function _affectedrows()
 | 
        
           |  |  | 156 | 	{
 | 
        
           |  |  | 157 | 		return $this->GetOne('select @@rowcount');
 | 
        
           |  |  | 158 | 	}
 | 
        
           |  |  | 159 |   | 
        
           |  |  | 160 | 	var $_dropSeqSQL = "drop table %s";
 | 
        
           |  |  | 161 |   | 
        
           |  |  | 162 | 	function CreateSequence($seq='adodbseq',$start=1)
 | 
        
           |  |  | 163 | 	{
 | 
        
           |  |  | 164 |   | 
        
           |  |  | 165 | 		$this->Execute('BEGIN TRANSACTION adodbseq');
 | 
        
           |  |  | 166 | 		$start -= 1;
 | 
        
           |  |  | 167 | 		$this->Execute("create table $seq (id float(53))");
 | 
        
           |  |  | 168 | 		$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
 | 
        
           |  |  | 169 | 		if (!$ok) {
 | 
        
           |  |  | 170 | 				$this->Execute('ROLLBACK TRANSACTION adodbseq');
 | 
        
           |  |  | 171 | 				return false;
 | 
        
           |  |  | 172 | 		}
 | 
        
           |  |  | 173 | 		$this->Execute('COMMIT TRANSACTION adodbseq'); 
 | 
        
           |  |  | 174 | 		return true;
 | 
        
           |  |  | 175 | 	}
 | 
        
           |  |  | 176 |   | 
        
           |  |  | 177 | 	function GenID($seq='adodbseq',$start=1)
 | 
        
           |  |  | 178 | 	{
 | 
        
           |  |  | 179 | 		//$this->debug=1;
 | 
        
           |  |  | 180 | 		$this->Execute('BEGIN TRANSACTION adodbseq');
 | 
        
           |  |  | 181 | 		$ok = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
 | 
        
           |  |  | 182 | 		if (!$ok) {
 | 
        
           |  |  | 183 | 			$this->Execute("create table $seq (id float(53))");
 | 
        
           |  |  | 184 | 			$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
 | 
        
           |  |  | 185 | 			if (!$ok) {
 | 
        
           |  |  | 186 | 				$this->Execute('ROLLBACK TRANSACTION adodbseq');
 | 
        
           |  |  | 187 | 				return false;
 | 
        
           |  |  | 188 | 			}
 | 
        
           |  |  | 189 | 			$this->Execute('COMMIT TRANSACTION adodbseq'); 
 | 
        
           |  |  | 190 | 			return $start;
 | 
        
           |  |  | 191 | 		}
 | 
        
           |  |  | 192 | 		$num = $this->GetOne("select id from $seq");
 | 
        
           |  |  | 193 | 		$this->Execute('COMMIT TRANSACTION adodbseq'); 
 | 
        
           |  |  | 194 | 		return $num;
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 | 		// in old implementation, pre 1.90, we returned GUID...
 | 
        
           |  |  | 197 | 		//return $this->GetOne("SELECT CONVERT(varchar(255), NEWID()) AS 'Char'");
 | 
        
           |  |  | 198 | 	}
 | 
        
           |  |  | 199 |   | 
        
           |  |  | 200 |   | 
        
           |  |  | 201 | 	function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
 | 
        
           |  |  | 202 | 	{
 | 
        
           |  |  | 203 | 		if ($nrows > 0 && $offset <= 0) {
 | 
        
           |  |  | 204 | 			$sql = preg_replace(
 | 
        
           |  |  | 205 | 				'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
 | 
        
           |  |  | 206 | 			$rs =& $this->Execute($sql,$inputarr);
 | 
        
           |  |  | 207 | 		} else
 | 
        
           |  |  | 208 | 			$rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
 | 
        
           |  |  | 209 |   | 
        
           |  |  | 210 | 		return $rs;
 | 
        
           |  |  | 211 | 	}
 | 
        
           |  |  | 212 |   | 
        
           |  |  | 213 |   | 
        
           |  |  | 214 | 	// Format date column in sql string given an input format that understands Y M D
 | 
        
           |  |  | 215 | 	function SQLDate($fmt, $col=false)
 | 
        
           |  |  | 216 | 	{	
 | 
        
           |  |  | 217 | 		if (!$col) $col = $this->sysTimeStamp;
 | 
        
           |  |  | 218 | 		$s = '';
 | 
        
           |  |  | 219 |   | 
        
           |  |  | 220 | 		$len = strlen($fmt);
 | 
        
           |  |  | 221 | 		for ($i=0; $i < $len; $i++) {
 | 
        
           |  |  | 222 | 			if ($s) $s .= '+';
 | 
        
           |  |  | 223 | 			$ch = $fmt[$i];
 | 
        
           |  |  | 224 | 			switch($ch) {
 | 
        
           |  |  | 225 | 			case 'Y':
 | 
        
           |  |  | 226 | 			case 'y':
 | 
        
           |  |  | 227 | 				$s .= "datename(yyyy,$col)";
 | 
        
           |  |  | 228 | 				break;
 | 
        
           |  |  | 229 | 			case 'M':
 | 
        
           |  |  | 230 | 				$s .= "convert(char(3),$col,0)";
 | 
        
           |  |  | 231 | 				break;
 | 
        
           |  |  | 232 | 			case 'm':
 | 
        
           |  |  | 233 | 				$s .= "replace(str(month($col),2),' ','0')";
 | 
        
           |  |  | 234 | 				break;
 | 
        
           |  |  | 235 | 			case 'Q':
 | 
        
           |  |  | 236 | 			case 'q':
 | 
        
           |  |  | 237 | 				$s .= "datename(quarter,$col)";
 | 
        
           |  |  | 238 | 				break;
 | 
        
           |  |  | 239 | 			case 'D':
 | 
        
           |  |  | 240 | 			case 'd':
 | 
        
           |  |  | 241 | 				$s .= "replace(str(day($col),2),' ','0')";
 | 
        
           |  |  | 242 | 				break;
 | 
        
           |  |  | 243 | 			case 'h':
 | 
        
           |  |  | 244 | 				$s .= "substring(convert(char(14),$col,0),13,2)";
 | 
        
           |  |  | 245 | 				break;
 | 
        
           |  |  | 246 |   | 
        
           |  |  | 247 | 			case 'H':
 | 
        
           |  |  | 248 | 				$s .= "replace(str(datepart(hh,$col),2),' ','0')";
 | 
        
           |  |  | 249 | 				break;
 | 
        
           |  |  | 250 |   | 
        
           |  |  | 251 | 			case 'i':
 | 
        
           |  |  | 252 | 				$s .= "replace(str(datepart(mi,$col),2),' ','0')";
 | 
        
           |  |  | 253 | 				break;
 | 
        
           |  |  | 254 | 			case 's':
 | 
        
           |  |  | 255 | 				$s .= "replace(str(datepart(ss,$col),2),' ','0')";
 | 
        
           |  |  | 256 | 				break;
 | 
        
           |  |  | 257 | 			case 'a':
 | 
        
           |  |  | 258 | 			case 'A':
 | 
        
           |  |  | 259 | 				$s .= "substring(convert(char(19),$col,0),18,2)";
 | 
        
           |  |  | 260 | 				break;
 | 
        
           |  |  | 261 |   | 
        
           |  |  | 262 | 			default:
 | 
        
           |  |  | 263 | 				if ($ch == '\\') {
 | 
        
           |  |  | 264 | 					$i++;
 | 
        
           |  |  | 265 | 					$ch = substr($fmt,$i,1);
 | 
        
           |  |  | 266 | 				}
 | 
        
           |  |  | 267 | 				$s .= $this->qstr($ch);
 | 
        
           |  |  | 268 | 				break;
 | 
        
           |  |  | 269 | 			}
 | 
        
           |  |  | 270 | 		}
 | 
        
           |  |  | 271 | 		return $s;
 | 
        
           |  |  | 272 | 	}
 | 
        
           |  |  | 273 |   | 
        
           |  |  | 274 |   | 
        
           |  |  | 275 | 	function BeginTrans()
 | 
        
           |  |  | 276 | 	{
 | 
        
           |  |  | 277 | 		if ($this->transOff) return true; 
 | 
        
           |  |  | 278 | 		$this->transCnt += 1;
 | 
        
           |  |  | 279 | 	   	$this->Execute('BEGIN TRAN');
 | 
        
           |  |  | 280 | 	   	return true;
 | 
        
           |  |  | 281 | 	}
 | 
        
           |  |  | 282 |   | 
        
           |  |  | 283 | 	function CommitTrans($ok=true) 
 | 
        
           |  |  | 284 | 	{ 
 | 
        
           |  |  | 285 | 		if ($this->transOff) return true; 
 | 
        
           |  |  | 286 | 		if (!$ok) return $this->RollbackTrans();
 | 
        
           |  |  | 287 | 		if ($this->transCnt) $this->transCnt -= 1;
 | 
        
           |  |  | 288 | 		$this->Execute('COMMIT TRAN');
 | 
        
           |  |  | 289 | 		return true;
 | 
        
           |  |  | 290 | 	}
 | 
        
           |  |  | 291 | 	function RollbackTrans()
 | 
        
           |  |  | 292 | 	{
 | 
        
           |  |  | 293 | 		if ($this->transOff) return true; 
 | 
        
           |  |  | 294 | 		if ($this->transCnt) $this->transCnt -= 1;
 | 
        
           |  |  | 295 | 		$this->Execute('ROLLBACK TRAN');
 | 
        
           |  |  | 296 | 		return true;
 | 
        
           |  |  | 297 | 	}
 | 
        
           |  |  | 298 |   | 
        
           |  |  | 299 | 	/*
 | 
        
           |  |  | 300 | 		Usage:
 | 
        
           |  |  | 301 |   | 
        
           |  |  | 302 | 		$this->BeginTrans();
 | 
        
           |  |  | 303 | 		$this->RowLock('table1,table2','table1.id=33 and table2.id=table1.id'); # lock row 33 for both tables
 | 
        
           |  |  | 304 |   | 
        
           |  |  | 305 | 		# some operation on both tables table1 and table2
 | 
        
           |  |  | 306 |   | 
        
           |  |  | 307 | 		$this->CommitTrans();
 | 
        
           |  |  | 308 |   | 
        
           |  |  | 309 | 		See http://www.swynk.com/friends/achigrik/SQL70Locks.asp
 | 
        
           |  |  | 310 | 	*/
 | 
        
           |  |  | 311 | 	function RowLock($tables,$where,$flds='top 1 null as ignore') 
 | 
        
           |  |  | 312 | 	{
 | 
        
           |  |  | 313 | 		if (!$this->transCnt) $this->BeginTrans();
 | 
        
           |  |  | 314 | 		return $this->GetOne("select $flds from $tables with (ROWLOCK,HOLDLOCK) where $where");
 | 
        
           |  |  | 315 | 	}
 | 
        
           |  |  | 316 |   | 
        
           |  |  | 317 |   | 
        
           |  |  | 318 | 	function &MetaIndexes($table,$primary=false)
 | 
        
           |  |  | 319 | 	{
 | 
        
           |  |  | 320 | 		$table = $this->qstr($table);
 | 
        
           |  |  | 321 |   | 
        
           |  |  | 322 | 		$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno, 
 | 
        
           |  |  | 323 | 			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,
 | 
        
           |  |  | 324 | 			CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
 | 
        
           |  |  | 325 | 			FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id 
 | 
        
           |  |  | 326 | 			INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid 
 | 
        
           |  |  | 327 | 			INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
 | 
        
           |  |  | 328 | 			WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND O.Name LIKE $table
 | 
        
           |  |  | 329 | 			ORDER BY O.name, I.Name, K.keyno";
 | 
        
           |  |  | 330 |   | 
        
           |  |  | 331 | 		global $ADODB_FETCH_MODE;
 | 
        
           |  |  | 332 | 		$save = $ADODB_FETCH_MODE;
 | 
        
           |  |  | 333 |         $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 | 
        
           |  |  | 334 |         if ($this->fetchMode !== FALSE) {
 | 
        
           |  |  | 335 |         	$savem = $this->SetFetchMode(FALSE);
 | 
        
           |  |  | 336 |         }
 | 
        
           |  |  | 337 |   | 
        
           |  |  | 338 |         $rs = $this->Execute($sql);
 | 
        
           |  |  | 339 |         if (isset($savem)) {
 | 
        
           |  |  | 340 |         	$this->SetFetchMode($savem);
 | 
        
           |  |  | 341 |         }
 | 
        
           |  |  | 342 |         $ADODB_FETCH_MODE = $save;
 | 
        
           |  |  | 343 |   | 
        
           |  |  | 344 |         if (!is_object($rs)) {
 | 
        
           |  |  | 345 |         	return FALSE;
 | 
        
           |  |  | 346 |         }
 | 
        
           |  |  | 347 |   | 
        
           |  |  | 348 | 		$indexes = array();
 | 
        
           |  |  | 349 | 		while ($row = $rs->FetchRow()) {
 | 
        
           |  |  | 350 | 			if (!$primary && $row[5]) continue;
 | 
        
           |  |  | 351 |   | 
        
           |  |  | 352 |             $indexes[$row[0]]['unique'] = $row[6];
 | 
        
           |  |  | 353 |             $indexes[$row[0]]['columns'][] = $row[1];
 | 
        
           |  |  | 354 |     	}
 | 
        
           |  |  | 355 |         return $indexes;
 | 
        
           |  |  | 356 | 	}
 | 
        
           |  |  | 357 |   | 
        
           |  |  | 358 | 	function MetaForeignKeys($table, $owner=false, $upper=false)
 | 
        
           |  |  | 359 | 	{
 | 
        
           |  |  | 360 | 	global $ADODB_FETCH_MODE;
 | 
        
           |  |  | 361 |   | 
        
           |  |  | 362 | 		$save = $ADODB_FETCH_MODE;
 | 
        
           |  |  | 363 | 		$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 | 
        
           |  |  | 364 | 		$table = $this->qstr(strtoupper($table));
 | 
        
           |  |  | 365 |   | 
        
           |  |  | 366 | 		$sql = 
 | 
        
           |  |  | 367 | "select object_name(constid) as constraint_name,
 | 
        
           |  |  | 368 | 	col_name(fkeyid, fkey) as column_name,
 | 
        
           |  |  | 369 | 	object_name(rkeyid) as referenced_table_name,
 | 
        
           |  |  | 370 |    	col_name(rkeyid, rkey) as referenced_column_name
 | 
        
           |  |  | 371 | from sysforeignkeys
 | 
        
           |  |  | 372 | where upper(object_name(fkeyid)) = $table
 | 
        
           |  |  | 373 | order by constraint_name, referenced_table_name, keyno";
 | 
        
           |  |  | 374 |   | 
        
           |  |  | 375 | 		$constraints =& $this->GetArray($sql);
 | 
        
           |  |  | 376 |   | 
        
           |  |  | 377 | 		$ADODB_FETCH_MODE = $save;
 | 
        
           |  |  | 378 |   | 
        
           |  |  | 379 | 		$arr = false;
 | 
        
           |  |  | 380 | 		foreach($constraints as $constr) {
 | 
        
           |  |  | 381 | 			//print_r($constr);
 | 
        
           |  |  | 382 | 			$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3]; 
 | 
        
           |  |  | 383 | 		}
 | 
        
           |  |  | 384 | 		if (!$arr) return false;
 | 
        
           |  |  | 385 |   | 
        
           |  |  | 386 | 		$arr2 = false;
 | 
        
           |  |  | 387 |   | 
        
           |  |  | 388 | 		foreach($arr as $k => $v) {
 | 
        
           |  |  | 389 | 			foreach($v as $a => $b) {
 | 
        
           |  |  | 390 | 				if ($upper) $a = strtoupper($a);
 | 
        
           |  |  | 391 | 				$arr2[$a] = $b;
 | 
        
           |  |  | 392 | 			}
 | 
        
           |  |  | 393 | 		}
 | 
        
           |  |  | 394 | 		return $arr2;
 | 
        
           |  |  | 395 | 	}
 | 
        
           |  |  | 396 |   | 
        
           |  |  | 397 | 	//From: Fernando Moreira <FMoreira@imediata.pt>
 | 
        
           |  |  | 398 | 	function MetaDatabases() 
 | 
        
           |  |  | 399 | 	{ 
 | 
        
           |  |  | 400 | 		if(@mssql_select_db("master")) { 
 | 
        
           |  |  | 401 | 				 $qry=$this->metaDatabasesSQL; 
 | 
        
           |  |  | 402 | 				 if($rs=@mssql_query($qry)){ 
 | 
        
           |  |  | 403 | 						 $tmpAr=$ar=array(); 
 | 
        
           |  |  | 404 | 						 while($tmpAr=@mssql_fetch_row($rs)) 
 | 
        
           |  |  | 405 | 								 $ar[]=$tmpAr[0]; 
 | 
        
           |  |  | 406 | 						@mssql_select_db($this->database); 
 | 
        
           |  |  | 407 | 						 if(sizeof($ar)) 
 | 
        
           |  |  | 408 | 								 return($ar); 
 | 
        
           |  |  | 409 | 						 else 
 | 
        
           |  |  | 410 | 								 return(false); 
 | 
        
           |  |  | 411 | 				 } else { 
 | 
        
           |  |  | 412 | 						 @mssql_select_db($this->database); 
 | 
        
           |  |  | 413 | 						 return(false); 
 | 
        
           |  |  | 414 | 				 } 
 | 
        
           |  |  | 415 | 		 } 
 | 
        
           |  |  | 416 | 		 return(false); 
 | 
        
           |  |  | 417 | 	} 
 | 
        
           |  |  | 418 |   | 
        
           |  |  | 419 | 	// "Stein-Aksel Basma" <basma@accelero.no>
 | 
        
           |  |  | 420 | 	// tested with MSSQL 2000
 | 
        
           |  |  | 421 | 	function &MetaPrimaryKeys($table)
 | 
        
           |  |  | 422 | 	{
 | 
        
           |  |  | 423 | 	global $ADODB_FETCH_MODE;
 | 
        
           |  |  | 424 |   | 
        
           |  |  | 425 | 		$schema = '';
 | 
        
           |  |  | 426 | 		$this->_findschema($table,$schema);
 | 
        
           |  |  | 427 | 		if (!$schema) $schema = $this->database;
 | 
        
           |  |  | 428 | 		if ($schema) $schema = "and k.table_catalog like '$schema%'"; 
 | 
        
           |  |  | 429 |   | 
        
           |  |  | 430 | 		$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
 | 
        
           |  |  | 431 | 		information_schema.table_constraints tc 
 | 
        
           |  |  | 432 | 		where tc.constraint_name = k.constraint_name and tc.constraint_type =
 | 
        
           |  |  | 433 | 		'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
 | 
        
           |  |  | 434 |   | 
        
           |  |  | 435 | 		$savem = $ADODB_FETCH_MODE;
 | 
        
           |  |  | 436 | 		$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 | 
        
           |  |  | 437 | 		$a = $this->GetCol($sql);
 | 
        
           |  |  | 438 | 		$ADODB_FETCH_MODE = $savem;
 | 
        
           |  |  | 439 |   | 
        
           |  |  | 440 | 		if ($a && sizeof($a)>0) return $a;
 | 
        
           |  |  | 441 | 		$false = false;
 | 
        
           |  |  | 442 | 		return $false;	  
 | 
        
           |  |  | 443 | 	}
 | 
        
           |  |  | 444 |   | 
        
           |  |  | 445 |   | 
        
           |  |  | 446 | 	function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
 | 
        
           |  |  | 447 | 	{
 | 
        
           |  |  | 448 | 		if ($mask) {
 | 
        
           |  |  | 449 | 			$save = $this->metaTablesSQL;
 | 
        
           |  |  | 450 | 			$mask = $this->qstr(($mask));
 | 
        
           |  |  | 451 | 			$this->metaTablesSQL .= " AND name like $mask";
 | 
        
           |  |  | 452 | 		}
 | 
        
           |  |  | 453 | 		$ret =& ADOConnection::MetaTables($ttype,$showSchema);
 | 
        
           |  |  | 454 |   | 
        
           |  |  | 455 | 		if ($mask) {
 | 
        
           |  |  | 456 | 			$this->metaTablesSQL = $save;
 | 
        
           |  |  | 457 | 		}
 | 
        
           |  |  | 458 | 		return $ret;
 | 
        
           |  |  | 459 | 	}
 | 
        
           |  |  | 460 |   | 
        
           |  |  | 461 | 	function SelectDB($dbName) 
 | 
        
           |  |  | 462 | 	{
 | 
        
           |  |  | 463 | 		$this->database = $dbName;
 | 
        
           |  |  | 464 | 		$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
 | 
        
           |  |  | 465 | 		if ($this->_connectionID) {
 | 
        
           |  |  | 466 | 			return @mssql_select_db($dbName);		
 | 
        
           |  |  | 467 | 		}
 | 
        
           |  |  | 468 | 		else return false;	
 | 
        
           |  |  | 469 | 	}
 | 
        
           |  |  | 470 |   | 
        
           |  |  | 471 | 	function ErrorMsg() 
 | 
        
           |  |  | 472 | 	{
 | 
        
           |  |  | 473 | 		if (empty($this->_errorMsg)){
 | 
        
           |  |  | 474 | 			$this->_errorMsg = mssql_get_last_message();
 | 
        
           |  |  | 475 | 		}
 | 
        
           |  |  | 476 | 		return $this->_errorMsg;
 | 
        
           |  |  | 477 | 	}
 | 
        
           |  |  | 478 |   | 
        
           |  |  | 479 | 	function ErrorNo() 
 | 
        
           |  |  | 480 | 	{
 | 
        
           |  |  | 481 | 		if ($this->_logsql && $this->_errorCode !== false) return $this->_errorCode;
 | 
        
           |  |  | 482 | 		if (empty($this->_errorMsg)) {
 | 
        
           |  |  | 483 | 			$this->_errorMsg = mssql_get_last_message();
 | 
        
           |  |  | 484 | 		}
 | 
        
           |  |  | 485 | 		$id = @mssql_query("select @@ERROR",$this->_connectionID);
 | 
        
           |  |  | 486 | 		if (!$id) return false;
 | 
        
           |  |  | 487 | 		$arr = mssql_fetch_array($id);
 | 
        
           |  |  | 488 | 		@mssql_free_result($id);
 | 
        
           |  |  | 489 | 		if (is_array($arr)) return $arr[0];
 | 
        
           |  |  | 490 | 	   else return -1;
 | 
        
           |  |  | 491 | 	}
 | 
        
           |  |  | 492 |   | 
        
           |  |  | 493 | 	// returns true or false
 | 
        
           |  |  | 494 | 	function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
 | 
        
           |  |  | 495 | 	{
 | 
        
           |  |  | 496 | 		if (!function_exists('mssql_pconnect')) return null;
 | 
        
           |  |  | 497 | 		$this->_connectionID = mssql_connect($argHostname,$argUsername,$argPassword);
 | 
        
           |  |  | 498 | 		if ($this->_connectionID === false) return false;
 | 
        
           |  |  | 499 | 		if ($argDatabasename) return $this->SelectDB($argDatabasename);
 | 
        
           |  |  | 500 | 		return true;	
 | 
        
           |  |  | 501 | 	}
 | 
        
           |  |  | 502 |   | 
        
           |  |  | 503 |   | 
        
           |  |  | 504 | 	// returns true or false
 | 
        
           |  |  | 505 | 	function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
 | 
        
           |  |  | 506 | 	{
 | 
        
           |  |  | 507 | 		if (!function_exists('mssql_pconnect')) return null;
 | 
        
           |  |  | 508 | 		$this->_connectionID = mssql_pconnect($argHostname,$argUsername,$argPassword);
 | 
        
           |  |  | 509 | 		if ($this->_connectionID === false) return false;
 | 
        
           |  |  | 510 |   | 
        
           |  |  | 511 | 		// persistent connections can forget to rollback on crash, so we do it here.
 | 
        
           |  |  | 512 | 		if ($this->autoRollback) {
 | 
        
           |  |  | 513 | 			$cnt = $this->GetOne('select @@TRANCOUNT');
 | 
        
           |  |  | 514 | 			while (--$cnt >= 0) $this->Execute('ROLLBACK TRAN'); 
 | 
        
           |  |  | 515 | 		}
 | 
        
           |  |  | 516 | 		if ($argDatabasename) return $this->SelectDB($argDatabasename);
 | 
        
           |  |  | 517 | 		return true;	
 | 
        
           |  |  | 518 | 	}
 | 
        
           |  |  | 519 |   | 
        
           |  |  | 520 | 	function Prepare($sql)
 | 
        
           |  |  | 521 | 	{
 | 
        
           |  |  | 522 | 		$sqlarr = explode('?',$sql);
 | 
        
           |  |  | 523 | 		if (sizeof($sqlarr) <= 1) return $sql;
 | 
        
           |  |  | 524 | 		$sql2 = $sqlarr[0];
 | 
        
           |  |  | 525 | 		for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) {
 | 
        
           |  |  | 526 | 			$sql2 .=  '@P'.($i-1) . $sqlarr[$i];
 | 
        
           |  |  | 527 | 		} 
 | 
        
           |  |  | 528 | 		return array($sql,$this->qstr($sql2),$max);
 | 
        
           |  |  | 529 | 	}
 | 
        
           |  |  | 530 |   | 
        
           |  |  | 531 | 	function PrepareSP($sql)
 | 
        
           |  |  | 532 | 	{
 | 
        
           |  |  | 533 | 		if (!$this->_has_mssql_init) {
 | 
        
           |  |  | 534 | 			ADOConnection::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
 | 
        
           |  |  | 535 | 			return $sql;
 | 
        
           |  |  | 536 | 		}
 | 
        
           |  |  | 537 | 		$stmt = mssql_init($sql,$this->_connectionID);
 | 
        
           |  |  | 538 | 		if (!$stmt)  return $sql;
 | 
        
           |  |  | 539 | 		return array($sql,$stmt);
 | 
        
           |  |  | 540 | 	}
 | 
        
           |  |  | 541 |   | 
        
           |  |  | 542 | 	// returns concatenated string
 | 
        
           |  |  | 543 |     // MSSQL requires integers to be cast as strings
 | 
        
           |  |  | 544 |     // automatically cast every datatype to VARCHAR(255)
 | 
        
           |  |  | 545 |     // @author David Rogers (introspectshun)
 | 
        
           |  |  | 546 |     function Concat()
 | 
        
           |  |  | 547 |     {
 | 
        
           |  |  | 548 |             $s = "";
 | 
        
           |  |  | 549 |             $arr = func_get_args();
 | 
        
           |  |  | 550 |   | 
        
           |  |  | 551 |             // Split single record on commas, if possible
 | 
        
           |  |  | 552 |             if (sizeof($arr) == 1) {
 | 
        
           |  |  | 553 |                 foreach ($arr as $arg) {
 | 
        
           |  |  | 554 |                     $args = explode(',', $arg);
 | 
        
           |  |  | 555 |                 }
 | 
        
           |  |  | 556 |                 $arr = $args;
 | 
        
           |  |  | 557 |             }
 | 
        
           |  |  | 558 |   | 
        
           |  |  | 559 |             array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
 | 
        
           |  |  | 560 |             $s = implode('+',$arr);
 | 
        
           |  |  | 561 |             if (sizeof($arr) > 0) return "$s";
 | 
        
           |  |  | 562 |   | 
        
           |  |  | 563 | 			return '';
 | 
        
           |  |  | 564 |     }
 | 
        
           |  |  | 565 |   | 
        
           |  |  | 566 | 	/* 
 | 
        
           |  |  | 567 | 	Usage:
 | 
        
           |  |  | 568 | 		$stmt = $db->PrepareSP('SP_RUNSOMETHING'); -- takes 2 params, @myid and @group
 | 
        
           |  |  | 569 |   | 
        
           |  |  | 570 | 		# note that the parameter does not have @ in front!
 | 
        
           |  |  | 571 | 		$db->Parameter($stmt,$id,'myid');
 | 
        
           |  |  | 572 | 		$db->Parameter($stmt,$group,'group',false,64);
 | 
        
           |  |  | 573 | 		$db->Execute($stmt);
 | 
        
           |  |  | 574 |   | 
        
           |  |  | 575 | 		@param $stmt Statement returned by Prepare() or PrepareSP().
 | 
        
           |  |  | 576 | 		@param $var PHP variable to bind to. Can set to null (for isNull support).
 | 
        
           |  |  | 577 | 		@param $name Name of stored procedure variable name to bind to.
 | 
        
           |  |  | 578 | 		@param [$isOutput] Indicates direction of parameter 0/false=IN  1=OUT  2= IN/OUT. This is ignored in oci8.
 | 
        
           |  |  | 579 | 		@param [$maxLen] Holds an maximum length of the variable.
 | 
        
           |  |  | 580 | 		@param [$type] The data type of $var. Legal values depend on driver.
 | 
        
           |  |  | 581 |   | 
        
           |  |  | 582 | 		See mssql_bind documentation at php.net.
 | 
        
           |  |  | 583 | 	*/
 | 
        
           |  |  | 584 | 	function Parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=4000, $type=false)
 | 
        
           |  |  | 585 | 	{
 | 
        
           |  |  | 586 | 		if (!$this->_has_mssql_init) {
 | 
        
           |  |  | 587 | 			ADOConnection::outp( "Parameter: mssql_bind only available since PHP 4.1.0");
 | 
        
           |  |  | 588 | 			return false;
 | 
        
           |  |  | 589 | 		}
 | 
        
           |  |  | 590 |   | 
        
           |  |  | 591 | 		$isNull = is_null($var); // php 4.0.4 and above...
 | 
        
           |  |  | 592 |   | 
        
           |  |  | 593 | 		if ($type === false) 
 | 
        
           |  |  | 594 | 			switch(gettype($var)) {
 | 
        
           |  |  | 595 | 			default:
 | 
        
           |  |  | 596 | 			case 'string': $type = SQLCHAR; break;
 | 
        
           |  |  | 597 | 			case 'double': $type = SQLFLT8; break;
 | 
        
           |  |  | 598 | 			case 'integer': $type = SQLINT4; break;
 | 
        
           |  |  | 599 | 			case 'boolean': $type = SQLINT1; break; # SQLBIT not supported in 4.1.0
 | 
        
           |  |  | 600 | 			}
 | 
        
           |  |  | 601 |   | 
        
           |  |  | 602 | 		if  ($this->debug) {
 | 
        
           |  |  | 603 | 			$prefix = ($isOutput) ? 'Out' : 'In';
 | 
        
           |  |  | 604 | 			$ztype = (empty($type)) ? 'false' : $type;
 | 
        
           |  |  | 605 | 			ADOConnection::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
 | 
        
           |  |  | 606 | 		}
 | 
        
           |  |  | 607 | 		/*
 | 
        
           |  |  | 608 | 			See http://phplens.com/lens/lensforum/msgs.php?id=7231
 | 
        
           |  |  | 609 |   | 
        
           |  |  | 610 | 			RETVAL is HARD CODED into php_mssql extension:
 | 
        
           |  |  | 611 | 			The return value (a long integer value) is treated like a special OUTPUT parameter, 
 | 
        
           |  |  | 612 | 			called "RETVAL" (without the @). See the example at mssql_execute to 
 | 
        
           |  |  | 613 | 			see how it works. - type: one of this new supported PHP constants. 
 | 
        
           |  |  | 614 | 				SQLTEXT, SQLVARCHAR,SQLCHAR, SQLINT1,SQLINT2, SQLINT4, SQLBIT,SQLFLT8 
 | 
        
           |  |  | 615 | 		*/
 | 
        
           |  |  | 616 | 		if ($name !== 'RETVAL') $name = '@'.$name;
 | 
        
           |  |  | 617 | 		return mssql_bind($stmt[1], $name, $var, $type, $isOutput, $isNull, $maxLen);
 | 
        
           |  |  | 618 | 	}
 | 
        
           |  |  | 619 |   | 
        
           |  |  | 620 | 	/* 
 | 
        
           |  |  | 621 | 		Unfortunately, it appears that mssql cannot handle varbinary > 255 chars
 | 
        
           |  |  | 622 | 		So all your blobs must be of type "image".
 | 
        
           |  |  | 623 |   | 
        
           |  |  | 624 | 		Remember to set in php.ini the following...
 | 
        
           |  |  | 625 |   | 
        
           |  |  | 626 | 		; Valid range 0 - 2147483647. Default = 4096. 
 | 
        
           |  |  | 627 | 		mssql.textlimit = 0 ; zero to pass through 
 | 
        
           |  |  | 628 |   | 
        
           |  |  | 629 | 		; Valid range 0 - 2147483647. Default = 4096. 
 | 
        
           |  |  | 630 | 		mssql.textsize = 0 ; zero to pass through 
 | 
        
           |  |  | 631 | 	*/
 | 
        
           |  |  | 632 | 	function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
 | 
        
           |  |  | 633 | 	{
 | 
        
           |  |  | 634 |   | 
        
           |  |  | 635 | 		if (strtoupper($blobtype) == 'CLOB') {
 | 
        
           |  |  | 636 | 			$sql = "UPDATE $table SET $column='" . $val . "' WHERE $where";
 | 
        
           |  |  | 637 | 			return $this->Execute($sql) != false;
 | 
        
           |  |  | 638 | 		}
 | 
        
           |  |  | 639 | 		$sql = "UPDATE $table SET $column=0x".bin2hex($val)." WHERE $where";
 | 
        
           |  |  | 640 | 		return $this->Execute($sql) != false;
 | 
        
           |  |  | 641 | 	}
 | 
        
           |  |  | 642 |   | 
        
           |  |  | 643 | 	// returns query ID if successful, otherwise false
 | 
        
           |  |  | 644 | 	function _query($sql,$inputarr)
 | 
        
           |  |  | 645 | 	{
 | 
        
           |  |  | 646 | 		$this->_errorMsg = false;
 | 
        
           |  |  | 647 | 		if (is_array($inputarr)) {
 | 
        
           |  |  | 648 |   | 
        
           |  |  | 649 | 			# bind input params with sp_executesql: 
 | 
        
           |  |  | 650 | 			# see http://www.quest-pipelines.com/newsletter-v3/0402_F.htm
 | 
        
           |  |  | 651 | 			# works only with sql server 7 and newer
 | 
        
           |  |  | 652 | 			if (!is_array($sql)) $sql = $this->Prepare($sql);
 | 
        
           |  |  | 653 | 			$params = '';
 | 
        
           |  |  | 654 | 			$decl = '';
 | 
        
           |  |  | 655 | 			$i = 0;
 | 
        
           |  |  | 656 | 			foreach($inputarr as $v) {
 | 
        
           |  |  | 657 | 				if ($decl) {
 | 
        
           |  |  | 658 | 					$decl .= ', ';
 | 
        
           |  |  | 659 | 					$params .= ', ';
 | 
        
           |  |  | 660 | 				}	
 | 
        
           |  |  | 661 | 				if (is_string($v)) {
 | 
        
           |  |  | 662 | 					$len = strlen($v);
 | 
        
           |  |  | 663 | 					if ($len == 0) $len = 1;
 | 
        
           |  |  | 664 |   | 
        
           |  |  | 665 | 					if ($len > 4000 ) {
 | 
        
           |  |  | 666 | 						// NVARCHAR is max 4000 chars. Let's use NTEXT
 | 
        
           |  |  | 667 | 						$decl .= "@P$i NTEXT";
 | 
        
           |  |  | 668 | 					} else {
 | 
        
           |  |  | 669 | 						$decl .= "@P$i NVARCHAR($len)";
 | 
        
           |  |  | 670 | 					}
 | 
        
           |  |  | 671 |   | 
        
           |  |  | 672 | 					$params .= "@P$i=N". (strncmp($v,"'",1)==0? $v : $this->qstr($v));
 | 
        
           |  |  | 673 | 				} else if (is_integer($v)) {
 | 
        
           |  |  | 674 | 					$decl .= "@P$i INT";
 | 
        
           |  |  | 675 | 					$params .= "@P$i=".$v;
 | 
        
           |  |  | 676 | 				} else if (is_float($v)) {
 | 
        
           |  |  | 677 | 					$decl .= "@P$i FLOAT";
 | 
        
           |  |  | 678 | 					$params .= "@P$i=".$v;
 | 
        
           |  |  | 679 | 				} else if (is_bool($v)) {
 | 
        
           |  |  | 680 | 					$decl .= "@P$i INT"; # Used INT just in case BIT in not supported on the user's MSSQL version. It will cast appropriately.
 | 
        
           |  |  | 681 | 					$params .= "@P$i=".(($v)?'1':'0'); # True == 1 in MSSQL BIT fields and acceptable for storing logical true in an int field
 | 
        
           |  |  | 682 | 				} else {
 | 
        
           |  |  | 683 | 					$decl .= "@P$i CHAR"; # Used char because a type is required even when the value is to be NULL.
 | 
        
           |  |  | 684 | 					$params .= "@P$i=NULL";
 | 
        
           |  |  | 685 | 					}
 | 
        
           |  |  | 686 | 				$i += 1;
 | 
        
           |  |  | 687 | 			}
 | 
        
           |  |  | 688 | 			$decl = $this->qstr($decl);
 | 
        
           |  |  | 689 | 			if ($this->debug) ADOConnection::outp("<font size=-1>sp_executesql N{$sql[1]},N$decl,$params</font>");
 | 
        
           |  |  | 690 | 			$rez = mssql_query("sp_executesql N{$sql[1]},N$decl,$params");
 | 
        
           |  |  | 691 |   | 
        
           |  |  | 692 | 		} else if (is_array($sql)) {
 | 
        
           |  |  | 693 | 			# PrepareSP()
 | 
        
           |  |  | 694 | 			$rez = mssql_execute($sql[1]);
 | 
        
           |  |  | 695 |   | 
        
           |  |  | 696 | 		} else {
 | 
        
           |  |  | 697 | 			$rez = mssql_query($sql,$this->_connectionID);
 | 
        
           |  |  | 698 | 		}
 | 
        
           |  |  | 699 | 		return $rez;
 | 
        
           |  |  | 700 | 	}
 | 
        
           |  |  | 701 |   | 
        
           |  |  | 702 | 	// returns true or false
 | 
        
           |  |  | 703 | 	function _close()
 | 
        
           |  |  | 704 | 	{ 
 | 
        
           |  |  | 705 | 		if ($this->transCnt) $this->RollbackTrans();
 | 
        
           |  |  | 706 | 		$rez = @mssql_close($this->_connectionID);
 | 
        
           |  |  | 707 | 		$this->_connectionID = false;
 | 
        
           |  |  | 708 | 		return $rez;
 | 
        
           |  |  | 709 | 	}
 | 
        
           |  |  | 710 |   | 
        
           |  |  | 711 | 	// mssql uses a default date like Dec 30 2000 12:00AM
 | 
        
           |  |  | 712 | 	function UnixDate($v)
 | 
        
           |  |  | 713 | 	{
 | 
        
           |  |  | 714 | 		return ADORecordSet_array_mssql::UnixDate($v);
 | 
        
           |  |  | 715 | 	}
 | 
        
           |  |  | 716 |   | 
        
           |  |  | 717 | 	function UnixTimeStamp($v)
 | 
        
           |  |  | 718 | 	{
 | 
        
           |  |  | 719 | 		return ADORecordSet_array_mssql::UnixTimeStamp($v);
 | 
        
           |  |  | 720 | 	}	
 | 
        
           |  |  | 721 | }
 | 
        
           |  |  | 722 |   | 
        
           |  |  | 723 | /*--------------------------------------------------------------------------------------
 | 
        
           |  |  | 724 | 	 Class Name: Recordset
 | 
        
           |  |  | 725 | --------------------------------------------------------------------------------------*/
 | 
        
           |  |  | 726 |   | 
        
           |  |  | 727 | class ADORecordset_mssql extends ADORecordSet {	
 | 
        
           |  |  | 728 |   | 
        
           |  |  | 729 | 	var $databaseType = "mssql";
 | 
        
           |  |  | 730 | 	var $canSeek = true;
 | 
        
           |  |  | 731 | 	var $hasFetchAssoc; // see http://phplens.com/lens/lensforum/msgs.php?id=6083
 | 
        
           |  |  | 732 | 	// _mths works only in non-localised system
 | 
        
           |  |  | 733 |   | 
        
           |  |  | 734 | 	function ADORecordset_mssql($id,$mode=false)
 | 
        
           |  |  | 735 | 	{
 | 
        
           |  |  | 736 | 		// freedts check...
 | 
        
           |  |  | 737 | 		$this->hasFetchAssoc = function_exists('mssql_fetch_assoc');
 | 
        
           |  |  | 738 |   | 
        
           |  |  | 739 | 		if ($mode === false) { 
 | 
        
           |  |  | 740 | 			global $ADODB_FETCH_MODE;
 | 
        
           |  |  | 741 | 			$mode = $ADODB_FETCH_MODE;
 | 
        
           |  |  | 742 |   | 
        
           |  |  | 743 | 		}
 | 
        
           |  |  | 744 | 		$this->fetchMode = $mode;
 | 
        
           |  |  | 745 | 		return $this->ADORecordSet($id,$mode);
 | 
        
           |  |  | 746 | 	}
 | 
        
           |  |  | 747 |   | 
        
           |  |  | 748 |   | 
        
           |  |  | 749 | 	function _initrs()
 | 
        
           |  |  | 750 | 	{
 | 
        
           |  |  | 751 | 	GLOBAL $ADODB_COUNTRECS;	
 | 
        
           |  |  | 752 | 		$this->_numOfRows = ($ADODB_COUNTRECS)? @mssql_num_rows($this->_queryID):-1;
 | 
        
           |  |  | 753 | 		$this->_numOfFields = @mssql_num_fields($this->_queryID);
 | 
        
           |  |  | 754 | 	}
 | 
        
           |  |  | 755 |   | 
        
           |  |  | 756 |   | 
        
           |  |  | 757 | 	//Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
 | 
        
           |  |  | 758 | 	// get next resultset - requires PHP 4.0.5 or later
 | 
        
           |  |  | 759 | 	function NextRecordSet()
 | 
        
           |  |  | 760 | 	{
 | 
        
           |  |  | 761 | 		if (!mssql_next_result($this->_queryID)) return false;
 | 
        
           |  |  | 762 | 		$this->_inited = false;
 | 
        
           |  |  | 763 | 		$this->bind = false;
 | 
        
           |  |  | 764 | 		$this->_currentRow = -1;
 | 
        
           |  |  | 765 | 		$this->Init();
 | 
        
           |  |  | 766 | 		return true;
 | 
        
           |  |  | 767 | 	}
 | 
        
           |  |  | 768 |   | 
        
           |  |  | 769 | 	/* Use associative array to get fields array */
 | 
        
           |  |  | 770 | 	function Fields($colname)
 | 
        
           |  |  | 771 | 	{
 | 
        
           |  |  | 772 | 		if ($this->fetchMode != ADODB_FETCH_NUM) return $this->fields[$colname];
 | 
        
           |  |  | 773 | 		if (!$this->bind) {
 | 
        
           |  |  | 774 | 			$this->bind = array();
 | 
        
           |  |  | 775 | 			for ($i=0; $i < $this->_numOfFields; $i++) {
 | 
        
           |  |  | 776 | 				$o = $this->FetchField($i);
 | 
        
           |  |  | 777 | 				$this->bind[strtoupper($o->name)] = $i;
 | 
        
           |  |  | 778 | 			}
 | 
        
           |  |  | 779 | 		}
 | 
        
           |  |  | 780 |   | 
        
           |  |  | 781 | 		 return $this->fields[$this->bind[strtoupper($colname)]];
 | 
        
           |  |  | 782 | 	}
 | 
        
           |  |  | 783 |   | 
        
           |  |  | 784 | 	/*	Returns: an object containing field information. 
 | 
        
           |  |  | 785 | 		Get column information in the Recordset object. fetchField() can be used in order to obtain information about
 | 
        
           |  |  | 786 | 		fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
 | 
        
           |  |  | 787 | 		fetchField() is retrieved.	*/
 | 
        
           |  |  | 788 |   | 
        
           |  |  | 789 | 	function &FetchField($fieldOffset = -1) 
 | 
        
           |  |  | 790 | 	{
 | 
        
           |  |  | 791 | 		if ($fieldOffset != -1) {
 | 
        
           |  |  | 792 | 			$f = @mssql_fetch_field($this->_queryID, $fieldOffset);
 | 
        
           |  |  | 793 | 		}
 | 
        
           |  |  | 794 | 		else if ($fieldOffset == -1) {	/*	The $fieldOffset argument is not provided thus its -1 	*/
 | 
        
           |  |  | 795 | 			$f = @mssql_fetch_field($this->_queryID);
 | 
        
           |  |  | 796 | 		}
 | 
        
           |  |  | 797 | 		$false = false;
 | 
        
           |  |  | 798 | 		if (empty($f)) return $false;
 | 
        
           |  |  | 799 | 		return $f;
 | 
        
           |  |  | 800 | 	}
 | 
        
           |  |  | 801 |   | 
        
           |  |  | 802 | 	function _seek($row) 
 | 
        
           |  |  | 803 | 	{
 | 
        
           |  |  | 804 | 		return @mssql_data_seek($this->_queryID, $row);
 | 
        
           |  |  | 805 | 	}
 | 
        
           |  |  | 806 |   | 
        
           |  |  | 807 | 	// speedup
 | 
        
           |  |  | 808 | 	function MoveNext() 
 | 
        
           |  |  | 809 | 	{
 | 
        
           |  |  | 810 | 		if ($this->EOF) return false;
 | 
        
           |  |  | 811 |   | 
        
           |  |  | 812 | 		$this->_currentRow++;
 | 
        
           |  |  | 813 |   | 
        
           |  |  | 814 | 		if ($this->fetchMode & ADODB_FETCH_ASSOC) {
 | 
        
           |  |  | 815 | 			if ($this->fetchMode & ADODB_FETCH_NUM) {
 | 
        
           |  |  | 816 | 				//ADODB_FETCH_BOTH mode
 | 
        
           |  |  | 817 | 				$this->fields = @mssql_fetch_array($this->_queryID);
 | 
        
           |  |  | 818 | 			}
 | 
        
           |  |  | 819 | 			else {
 | 
        
           |  |  | 820 | 				if ($this->hasFetchAssoc) {// only for PHP 4.2.0 or later
 | 
        
           |  |  | 821 | 					 $this->fields = @mssql_fetch_assoc($this->_queryID);
 | 
        
           |  |  | 822 | 				} else {
 | 
        
           |  |  | 823 | 					$flds = @mssql_fetch_array($this->_queryID);
 | 
        
           |  |  | 824 | 					if (is_array($flds)) {
 | 
        
           |  |  | 825 | 						$fassoc = array();
 | 
        
           |  |  | 826 | 						foreach($flds as $k => $v) {
 | 
        
           |  |  | 827 | 							if (is_numeric($k)) continue;
 | 
        
           |  |  | 828 | 							$fassoc[$k] = $v;
 | 
        
           |  |  | 829 | 						}
 | 
        
           |  |  | 830 | 						$this->fields = $fassoc;
 | 
        
           |  |  | 831 | 					} else
 | 
        
           |  |  | 832 | 						$this->fields = false;
 | 
        
           |  |  | 833 | 				}
 | 
        
           |  |  | 834 | 			}
 | 
        
           |  |  | 835 |   | 
        
           |  |  | 836 | 			if (is_array($this->fields)) {
 | 
        
           |  |  | 837 | 				if (ADODB_ASSOC_CASE == 0) {
 | 
        
           |  |  | 838 | 					foreach($this->fields as $k=>$v) {
 | 
        
           |  |  | 839 | 						$this->fields[strtolower($k)] = $v;
 | 
        
           |  |  | 840 | 					}
 | 
        
           |  |  | 841 | 				} else if (ADODB_ASSOC_CASE == 1) {
 | 
        
           |  |  | 842 | 					foreach($this->fields as $k=>$v) {
 | 
        
           |  |  | 843 | 						$this->fields[strtoupper($k)] = $v;
 | 
        
           |  |  | 844 | 					}
 | 
        
           |  |  | 845 | 				}
 | 
        
           |  |  | 846 | 			}
 | 
        
           |  |  | 847 | 		} else {
 | 
        
           |  |  | 848 | 			$this->fields = @mssql_fetch_row($this->_queryID);
 | 
        
           |  |  | 849 | 		}
 | 
        
           |  |  | 850 | 		if ($this->fields) return true;
 | 
        
           |  |  | 851 | 		$this->EOF = true;
 | 
        
           |  |  | 852 |   | 
        
           |  |  | 853 | 		return false;
 | 
        
           |  |  | 854 | 	}
 | 
        
           |  |  | 855 |   | 
        
           |  |  | 856 |   | 
        
           |  |  | 857 | 	// INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
 | 
        
           |  |  | 858 | 	// also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
 | 
        
           |  |  | 859 | 	function _fetch($ignore_fields=false) 
 | 
        
           |  |  | 860 | 	{
 | 
        
           |  |  | 861 | 		if ($this->fetchMode & ADODB_FETCH_ASSOC) {
 | 
        
           |  |  | 862 | 			if ($this->fetchMode & ADODB_FETCH_NUM) {
 | 
        
           |  |  | 863 | 				//ADODB_FETCH_BOTH mode
 | 
        
           |  |  | 864 | 				$this->fields = @mssql_fetch_array($this->_queryID);
 | 
        
           |  |  | 865 | 			} else {
 | 
        
           |  |  | 866 | 				if ($this->hasFetchAssoc) // only for PHP 4.2.0 or later
 | 
        
           |  |  | 867 | 					$this->fields = @mssql_fetch_assoc($this->_queryID);
 | 
        
           |  |  | 868 | 				else {
 | 
        
           |  |  | 869 | 					$this->fields = @mssql_fetch_array($this->_queryID);
 | 
        
           |  |  | 870 | 					if (@is_array($$this->fields)) {
 | 
        
           |  |  | 871 | 						$fassoc = array();
 | 
        
           |  |  | 872 | 						foreach($$this->fields as $k => $v) {
 | 
        
           |  |  | 873 | 							if (is_integer($k)) continue;
 | 
        
           |  |  | 874 | 							$fassoc[$k] = $v;
 | 
        
           |  |  | 875 | 						}
 | 
        
           |  |  | 876 | 						$this->fields = $fassoc;
 | 
        
           |  |  | 877 | 					}
 | 
        
           |  |  | 878 | 				}
 | 
        
           |  |  | 879 | 			}
 | 
        
           |  |  | 880 |   | 
        
           |  |  | 881 | 			if (!$this->fields) {
 | 
        
           |  |  | 882 | 			} else if (ADODB_ASSOC_CASE == 0) {
 | 
        
           |  |  | 883 | 				foreach($this->fields as $k=>$v) {
 | 
        
           |  |  | 884 | 					$this->fields[strtolower($k)] = $v;
 | 
        
           |  |  | 885 | 				}
 | 
        
           |  |  | 886 | 			} else if (ADODB_ASSOC_CASE == 1) {
 | 
        
           |  |  | 887 | 				foreach($this->fields as $k=>$v) {
 | 
        
           |  |  | 888 | 					$this->fields[strtoupper($k)] = $v;
 | 
        
           |  |  | 889 | 				}
 | 
        
           |  |  | 890 | 			}
 | 
        
           |  |  | 891 | 		} else {
 | 
        
           |  |  | 892 | 			$this->fields = @mssql_fetch_row($this->_queryID);
 | 
        
           |  |  | 893 | 		}
 | 
        
           |  |  | 894 | 		return $this->fields;
 | 
        
           |  |  | 895 | 	}
 | 
        
           |  |  | 896 |   | 
        
           |  |  | 897 | 	/*	close() only needs to be called if you are worried about using too much memory while your script
 | 
        
           |  |  | 898 | 		is running. All associated result memory for the specified result identifier will automatically be freed.	*/
 | 
        
           |  |  | 899 |   | 
        
           |  |  | 900 | 	function _close() 
 | 
        
           |  |  | 901 | 	{
 | 
        
           |  |  | 902 | 		$rez = mssql_free_result($this->_queryID);	
 | 
        
           |  |  | 903 | 		$this->_queryID = false;
 | 
        
           |  |  | 904 | 		return $rez;
 | 
        
           |  |  | 905 | 	}
 | 
        
           |  |  | 906 | 	// mssql uses a default date like Dec 30 2000 12:00AM
 | 
        
           |  |  | 907 | 	function UnixDate($v)
 | 
        
           |  |  | 908 | 	{
 | 
        
           |  |  | 909 | 		return ADORecordSet_array_mssql::UnixDate($v);
 | 
        
           |  |  | 910 | 	}
 | 
        
           |  |  | 911 |   | 
        
           |  |  | 912 | 	function UnixTimeStamp($v)
 | 
        
           |  |  | 913 | 	{
 | 
        
           |  |  | 914 | 		return ADORecordSet_array_mssql::UnixTimeStamp($v);
 | 
        
           |  |  | 915 | 	}
 | 
        
           |  |  | 916 |   | 
        
           |  |  | 917 | }
 | 
        
           |  |  | 918 |   | 
        
           |  |  | 919 |   | 
        
           |  |  | 920 | class ADORecordSet_array_mssql extends ADORecordSet_array {
 | 
        
           |  |  | 921 | 	function ADORecordSet_array_mssql($id=-1,$mode=false) 
 | 
        
           |  |  | 922 | 	{
 | 
        
           |  |  | 923 | 		$this->ADORecordSet_array($id,$mode);
 | 
        
           |  |  | 924 | 	}
 | 
        
           |  |  | 925 |   | 
        
           |  |  | 926 | 		// mssql uses a default date like Dec 30 2000 12:00AM
 | 
        
           |  |  | 927 | 	function UnixDate($v)
 | 
        
           |  |  | 928 | 	{
 | 
        
           |  |  | 929 |   | 
        
           |  |  | 930 | 		if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
 | 
        
           |  |  | 931 |   | 
        
           |  |  | 932 | 	global $ADODB_mssql_mths,$ADODB_mssql_date_order;
 | 
        
           |  |  | 933 |   | 
        
           |  |  | 934 | 		//Dec 30 2000 12:00AM 
 | 
        
           |  |  | 935 | 		if ($ADODB_mssql_date_order == 'dmy') {
 | 
        
           |  |  | 936 | 			if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
 | 
        
           |  |  | 937 | 				return parent::UnixDate($v);
 | 
        
           |  |  | 938 | 			}
 | 
        
           |  |  | 939 | 			if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
 | 
        
           |  |  | 940 |   | 
        
           |  |  | 941 | 			$theday = $rr[1];
 | 
        
           |  |  | 942 | 			$themth =  substr(strtoupper($rr[2]),0,3);
 | 
        
           |  |  | 943 | 		} else {
 | 
        
           |  |  | 944 | 			if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
 | 
        
           |  |  | 945 | 				return parent::UnixDate($v);
 | 
        
           |  |  | 946 | 			}
 | 
        
           |  |  | 947 | 			if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
 | 
        
           |  |  | 948 |   | 
        
           |  |  | 949 | 			$theday = $rr[2];
 | 
        
           |  |  | 950 | 			$themth = substr(strtoupper($rr[1]),0,3);
 | 
        
           |  |  | 951 | 		}
 | 
        
           |  |  | 952 | 		$themth = $ADODB_mssql_mths[$themth];
 | 
        
           |  |  | 953 | 		if ($themth <= 0) return false;
 | 
        
           |  |  | 954 | 		// h-m-s-MM-DD-YY
 | 
        
           |  |  | 955 | 		return  mktime(0,0,0,$themth,$theday,$rr[3]);
 | 
        
           |  |  | 956 | 	}
 | 
        
           |  |  | 957 |   | 
        
           |  |  | 958 | 	function UnixTimeStamp($v)
 | 
        
           |  |  | 959 | 	{
 | 
        
           |  |  | 960 |   | 
        
           |  |  | 961 | 		if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
 | 
        
           |  |  | 962 |   | 
        
           |  |  | 963 | 	global $ADODB_mssql_mths,$ADODB_mssql_date_order;
 | 
        
           |  |  | 964 |   | 
        
           |  |  | 965 | 		//Dec 30 2000 12:00AM
 | 
        
           |  |  | 966 | 		 if ($ADODB_mssql_date_order == 'dmy') {
 | 
        
           |  |  | 967 | 			 if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
 | 
        
           |  |  | 968 | 			,$v, $rr)) return parent::UnixTimeStamp($v);
 | 
        
           |  |  | 969 | 			if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
 | 
        
           |  |  | 970 |   | 
        
           |  |  | 971 | 			$theday = $rr[1];
 | 
        
           |  |  | 972 | 			$themth =  substr(strtoupper($rr[2]),0,3);
 | 
        
           |  |  | 973 | 		} else {
 | 
        
           |  |  | 974 | 			if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
 | 
        
           |  |  | 975 | 			,$v, $rr)) return parent::UnixTimeStamp($v);
 | 
        
           |  |  | 976 | 			if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
 | 
        
           |  |  | 977 |   | 
        
           |  |  | 978 | 			$theday = $rr[2];
 | 
        
           |  |  | 979 | 			$themth = substr(strtoupper($rr[1]),0,3);
 | 
        
           |  |  | 980 | 		}
 | 
        
           |  |  | 981 |   | 
        
           |  |  | 982 | 		$themth = $ADODB_mssql_mths[$themth];
 | 
        
           |  |  | 983 | 		if ($themth <= 0) return false;
 | 
        
           |  |  | 984 |   | 
        
           |  |  | 985 | 		switch (strtoupper($rr[6])) {
 | 
        
           |  |  | 986 | 		case 'P':
 | 
        
           |  |  | 987 | 			if ($rr[4]<12) $rr[4] += 12;
 | 
        
           |  |  | 988 | 			break;
 | 
        
           |  |  | 989 | 		case 'A':
 | 
        
           |  |  | 990 | 			if ($rr[4]==12) $rr[4] = 0;
 | 
        
           |  |  | 991 | 			break;
 | 
        
           |  |  | 992 | 		default:
 | 
        
           |  |  | 993 | 			break;
 | 
        
           |  |  | 994 | 		}
 | 
        
           |  |  | 995 | 		// h-m-s-MM-DD-YY
 | 
        
           |  |  | 996 | 		return  mktime($rr[4],$rr[5],0,$themth,$theday,$rr[3]);
 | 
        
           |  |  | 997 | 	}
 | 
        
           |  |  | 998 | }
 | 
        
           |  |  | 999 |   | 
        
           |  |  | 1000 | /*
 | 
        
           |  |  | 1001 | Code Example 1:
 | 
        
           |  |  | 1002 |   | 
        
           |  |  | 1003 | select 	object_name(constid) as constraint_name,
 | 
        
           |  |  | 1004 |        	object_name(fkeyid) as table_name, 
 | 
        
           |  |  | 1005 |         col_name(fkeyid, fkey) as column_name,
 | 
        
           |  |  | 1006 | 	object_name(rkeyid) as referenced_table_name,
 | 
        
           |  |  | 1007 |    	col_name(rkeyid, rkey) as referenced_column_name
 | 
        
           |  |  | 1008 | from sysforeignkeys
 | 
        
           |  |  | 1009 | where object_name(fkeyid) = x
 | 
        
           |  |  | 1010 | order by constraint_name, table_name, referenced_table_name,  keyno
 | 
        
           |  |  | 1011 |   | 
        
           |  |  | 1012 | Code Example 2:
 | 
        
           |  |  | 1013 | select 	constraint_name,
 | 
        
           |  |  | 1014 | 	column_name,
 | 
        
           |  |  | 1015 | 	ordinal_position
 | 
        
           |  |  | 1016 | from information_schema.key_column_usage
 | 
        
           |  |  | 1017 | where constraint_catalog = db_name()
 | 
        
           |  |  | 1018 | and table_name = x
 | 
        
           |  |  | 1019 | order by constraint_name, ordinal_position
 | 
        
           |  |  | 1020 |   | 
        
           |  |  | 1021 | http://www.databasejournal.com/scripts/article.php/1440551
 | 
        
           |  |  | 1022 | */
 | 
        
           |  |  | 1023 |   | 
        
           |  |  | 1024 | ?>
 |