3 V4.22 15 Apr 2004 (c) 2000-2004 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.
9 Latest version is available at http://php.weblogs.com/
11 Native mssql driver. Requires mssql client. Works on Windows.
12 To configure for Unix, see
13 http://phpbuilder.com/columns/alberto20000919.php3
17 //----------------------------------------------------------------
18 // MSSQL returns dates with the format Oct 13 2002 or 13 Oct 2002
19 // and this causes tons of problems because localized versions of
20 // MSSQL will return the dates in dmy or mdy order; and also the
21 // month strings depends on what language has been configured. The
22 // following two variables allow you to control the localization
25 // MORE LOCALIZATION INFO
26 // ----------------------
27 // To configure datetime, look for and modify sqlcommn.loc,
28 // typically found in c:\mssql\install
30 // http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
32 // CONVERT(char(12),datecol,120)
33 //----------------------------------------------------------------
35 // has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
36 if (ADODB_PHPVER >= 0x4300) {
37 // docs say 4.2.0, but testing shows only since 4.3.0 does it work!
38 @ini_set('mssql.datetimeconvert',0);
40 global $ADODB_mssql_mths; // array, months must be upper-case
42 $ADODB_mssql_date_order = 'mdy';
43 $ADODB_mssql_mths = array(
44 'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
45 'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
48 //---------------------------------------------------------------------------
49 // Call this to autoset $ADODB_mssql_date_order at the beginning of your code,
50 // just after you connect to the database. Supports mdy and dmy only.
51 // Not required for PHP 4.2.0 and above.
52 function AutoDetect_MSSQL_Date_Order($conn)
54 global $ADODB_mssql_date_order;
55 $adate = $conn->GetOne('select getdate()');
60 //ADOConnection::outp( "MSSQL: YYYY-MM-DD date format not supported currently");
62 $ADODB_mssql_date_order = 'dmy';
64 $ADODB_mssql_date_order = 'mdy';
68 class ADODB_mssql extends ADOConnection {
69 var $databaseType = "mssql";
70 var $dataProvider = "mssql";
71 var $replaceQuote = "''"; // string to use to replace quotes
72 var $fmtDate = "'Y-m-d'";
73 var $fmtTimeStamp = "'Y-m-d h:i:sA'";
74 var $hasInsertID = true;
75 var $substr = "substring";
77 var $upperCase = 'upper';
78 var $hasAffectedRows = true;
79 var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
80 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'))";
81 var $metaColumnsSQL = # xtype==61 is datetime
82 "select c.name,t.name,c.length,
83 (case when c.xusertype=61 then 0 else c.xprec end),
84 (case when c.xusertype=61 then 0 else c.xscale end)
85 from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
86 var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
88 var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
89 var $sysTimeStamp = 'GetDate()';
91 var $maxParameterLen = 4000;
92 var $arrayClass = 'ADORecordSet_array_mssql';
93 var $uniqueSort = true;
94 var $leftOuter = '*=';
95 var $rightOuter = '=*';
96 var $ansiOuter = true; // for mssql7 or later
97 var $poorAffectedRows = true;
98 var $identitySQL = 'select @@IDENTITY'; // 'select SCOPE_IDENTITY'; # for mssql 2000
99 var $uniqueOrderBy = true;
100 var $_bindInputArray = true;
102 function ADODB_mssql()
104 $this->_has_mssql_init = (strnatcmp(PHP_VERSION,'4.1.0')>=0);
107 function ServerInfo()
109 global $ADODB_FETCH_MODE;
111 $stmt = $this->PrepareSP('sp_server_info');
113 if ($this->fetchMode === false) {
114 $savem = $ADODB_FETCH_MODE;
115 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
117 $savem = $this->SetFetchMode(ADODB_FETCH_NUM);
119 $this->Parameter($stmt,$val,'attribute_id');
120 $row = $this->GetRow($stmt);
122 //$row = $this->GetRow("execute sp_server_info 2");
124 if ($this->fetchMode === false) {
125 $ADODB_FETCH_MODE = $savem;
127 $this->SetFetchMode($savem);
129 $arr['description'] = $row[2];
130 $arr['version'] = ADOConnection::_findvers($arr['description']);
134 function IfNull( $field, $ifNull )
136 return " ISNULL($field, $ifNull) "; // if MS SQL Server
142 // Returns the last IDENTITY value inserted into an IDENTITY column in
143 // the same scope. A scope is a module -- a stored procedure, trigger,
144 // function, or batch. Thus, two statements are in the same scope if
145 // they are in the same stored procedure, function, or batch.
146 return $this->GetOne($this->identitySQL);
149 function _affectedrows()
151 return $this->GetOne('select @@rowcount');
154 var $_dropSeqSQL = "drop table %s";
156 function CreateSequence($seq='adodbseq',$start=1)
159 $this->Execute("create table $seq (id float(53))");
160 $ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
162 $this->Execute('ROLLBACK TRANSACTION adodbseq');
165 $this->Execute('COMMIT TRANSACTION adodbseq');
169 function GenID($seq='adodbseq',$start=1)
172 $this->Execute('BEGIN TRANSACTION adodbseq');
173 $ok = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
175 $this->Execute("create table $seq (id float(53))");
176 $ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
178 $this->Execute('ROLLBACK TRANSACTION adodbseq');
181 $this->Execute('COMMIT TRANSACTION adodbseq');
184 $num = $this->GetOne("select id from $seq");
185 $this->Execute('COMMIT TRANSACTION adodbseq');
188 // in old implementation, pre 1.90, we returned GUID...
189 //return $this->GetOne("SELECT CONVERT(varchar(255), NEWID()) AS 'Char'");
192 function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
194 if ($nrows > 0 && $offset <= 0) {
196 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
197 $rs =& $this->Execute($sql,$inputarr);
199 $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
204 // Format date column in sql string given an input format that understands Y M D
205 function SQLDate($fmt, $col=false)
207 if (!$col) $col = $this->sysTimeStamp;
211 for ($i=0; $i < $len; $i++) {
217 $s .= "datename(yyyy,$col)";
220 $s .= "convert(char(3),$col,0)";
223 $s .= "replace(str(month($col),2),' ','0')";
227 $s .= "datename(quarter,$col)";
231 $s .= "replace(str(day($col),2),' ','0')";
234 $s .= "substring(convert(char(14),$col,0),13,2)";
238 $s .= "replace(str(datepart(hh,$col),2),' ','0')";
242 $s .= "replace(str(datepart(mi,$col),2),' ','0')";
245 $s .= "replace(str(datepart(ss,$col),2),' ','0')";
249 $s .= "substring(convert(char(19),$col,0),18,2)";
255 $ch = substr($fmt,$i,1);
257 $s .= $this->qstr($ch);
264 function BeginTrans()
266 if ($this->transOff) return true;
267 $this->transCnt += 1;
268 $this->Execute('BEGIN TRAN');
272 function CommitTrans($ok=true)
274 if ($this->transOff) return true;
275 if (!$ok) return $this->RollbackTrans();
276 if ($this->transCnt) $this->transCnt -= 1;
277 $this->Execute('COMMIT TRAN');
280 function RollbackTrans()
282 if ($this->transOff) return true;
283 if ($this->transCnt) $this->transCnt -= 1;
284 $this->Execute('ROLLBACK TRAN');
292 $this->RowLock('table1,table2','table1.id=33 and table2.id=table1.id'); # lock row 33 for both tables
294 # some operation on both tables table1 and table2
296 $this->CommitTrans();
298 See http://www.swynk.com/friends/achigrik/SQL70Locks.asp
300 function RowLock($tables,$where)
302 if (!$this->transCnt) $this->BeginTrans();
303 return $this->GetOne("select top 1 null as ignore from $tables with (ROWLOCK,HOLDLOCK) where $where");
306 function MetaForeignKeys($table, $owner=false, $upper=false)
308 global $ADODB_FETCH_MODE;
310 $save = $ADODB_FETCH_MODE;
311 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
312 $table = $this->qstr(strtoupper($table));
315 "select object_name(constid) as constraint_name,
316 col_name(fkeyid, fkey) as column_name,
317 object_name(rkeyid) as referenced_table_name,
318 col_name(rkeyid, rkey) as referenced_column_name
320 where upper(object_name(fkeyid)) = $table
321 order by constraint_name, referenced_table_name, keyno";
323 $constraints =& $this->GetArray($sql);
325 $ADODB_FETCH_MODE = $save;
328 foreach($constraints as $constr) {
330 $arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
332 if (!$arr) return false;
336 foreach($arr as $k => $v) {
337 foreach($v as $a => $b) {
338 if ($upper) $a = strtoupper($a);
345 //From: Fernando Moreira <FMoreira@imediata.pt>
346 function MetaDatabases()
348 if(@mssql_select_db("master")) {
349 $qry=$this->metaDatabasesSQL;
350 if($rs=@mssql_query($qry)){
352 while($tmpAr=@mssql_fetch_row($rs))
354 @mssql_select_db($this->databaseName);
360 @mssql_select_db($this->databaseName);
367 // "Stein-Aksel Basma" <basma@accelero.no>
368 // tested with MSSQL 2000
369 function MetaPrimaryKeys($table)
371 $sql = "select k.column_name from information_schema.key_column_usage k,
372 information_schema.table_constraints tc
373 where tc.constraint_name = k.constraint_name and tc.constraint_type =
374 'PRIMARY KEY' and k.table_name = '$table'";
376 $a = $this->GetCol($sql);
377 if ($a && sizeof($a)>0) return $a;
381 function &MetaTables($ttype=false,$showSchema=false,$mask=false)
384 $save = $this->metaTablesSQL;
385 $mask = $this->qstr(($mask));
386 $this->metaTablesSQL .= " AND name like $mask";
388 $ret =& ADOConnection::MetaTables($ttype,$showSchema);
391 $this->metaTablesSQL = $save;
396 function SelectDB($dbName)
398 $this->databaseName = $dbName;
399 if ($this->_connectionID) {
400 return @mssql_select_db($dbName);
407 if (empty($this->_errorMsg)){
408 $this->_errorMsg = mssql_get_last_message();
410 return $this->_errorMsg;
415 if ($this->_logsql && $this->_errorCode !== false) return $this->_errorCode;
416 if (empty($this->_errorMsg)) {
417 $this->_errorMsg = mssql_get_last_message();
419 $id = @mssql_query("select @@ERROR",$this->_connectionID);
420 if (!$id) return false;
421 $arr = mssql_fetch_array($id);
422 @mssql_free_result($id);
423 if (is_array($arr)) return $arr[0];
427 // returns true or false
428 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
430 if (!function_exists('mssql_pconnect')) return false;
431 $this->_connectionID = mssql_connect($argHostname,$argUsername,$argPassword);
432 if ($this->_connectionID === false) return false;
433 if ($argDatabasename) return $this->SelectDB($argDatabasename);
437 // returns true or false
438 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
440 if (!function_exists('mssql_pconnect')) return false;
441 $this->_connectionID = mssql_pconnect($argHostname,$argUsername,$argPassword);
442 if ($this->_connectionID === false) return false;
444 // persistent connections can forget to rollback on crash, so we do it here.
445 if ($this->autoRollback) {
446 $cnt = $this->GetOne('select @@TRANCOUNT');
447 while (--$cnt >= 0) $this->Execute('ROLLBACK TRAN');
449 if ($argDatabasename) return $this->SelectDB($argDatabasename);
453 function Prepare($sql)
455 $sqlarr = explode('?',$sql);
456 if (sizeof($sqlarr) <= 1) return $sql;
458 for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) {
459 $sql2 .= '@P'.($i-1) . $sqlarr[$i];
461 return array($sql,$this->qstr($sql2),$max);
464 function PrepareSP($sql)
466 if (!$this->_has_mssql_init) {
467 ADOConnection::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
470 $stmt = mssql_init($sql,$this->_connectionID);
471 if (!$stmt) return $sql;
472 return array($sql,$stmt);
477 $stmt = $db->PrepareSP('SP_RUNSOMETHING'); -- takes 2 params, @myid and @group
479 # note that the parameter does not have @ in front!
480 $db->Parameter($stmt,$id,'myid');
481 $db->Parameter($stmt,$group,'group',false,64);
484 @param $stmt Statement returned by Prepare() or PrepareSP().
485 @param $var PHP variable to bind to. Can set to null (for isNull support).
486 @param $name Name of stored procedure variable name to bind to.
487 @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
488 @param [$maxLen] Holds an maximum length of the variable.
489 @param [$type] The data type of $var. Legal values depend on driver.
491 See mssql_bind documentation at php.net.
493 function Parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=4000, $type=false)
495 if (!$this->_has_mssql_init) {
496 ADOConnection::outp( "Parameter: mssql_bind only available since PHP 4.1.0");
500 $isNull = is_null($var); // php 4.0.4 and above...
503 switch(gettype($var)) {
505 case 'string': $type = SQLCHAR; break;
506 case 'double': $type = SQLFLT8; break;
507 case 'integer': $type = SQLINT4; break;
508 case 'boolean': $type = SQLINT1; break; # SQLBIT not supported in 4.1.0
512 $prefix = ($isOutput) ? 'Out' : 'In';
513 $ztype = (empty($type)) ? 'false' : $type;
514 ADOConnection::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
517 See http://phplens.com/lens/lensforum/msgs.php?id=7231
519 RETVAL is HARD CODED into php_mssql extension:
520 The return value (a long integer value) is treated like a special OUTPUT parameter,
521 called "RETVAL" (without the @). See the example at mssql_execute to
522 see how it works. - type: one of this new supported PHP constants.
523 SQLTEXT, SQLVARCHAR,SQLCHAR, SQLINT1,SQLINT2, SQLINT4, SQLBIT,SQLFLT8
525 if ($name !== 'RETVAL') $name = '@'.$name;
526 return mssql_bind($stmt[1], $name, $var, $type, $isOutput, $isNull, $maxLen);
530 Unfortunately, it appears that mssql cannot handle varbinary > 255 chars
531 So all your blobs must be of type "image".
533 Remember to set in php.ini the following...
535 ; Valid range 0 - 2147483647. Default = 4096.
536 mssql.textlimit = 0 ; zero to pass through
538 ; Valid range 0 - 2147483647. Default = 4096.
539 mssql.textsize = 0 ; zero to pass through
541 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
543 $sql = "UPDATE $table SET $column=0x".bin2hex($val)." WHERE $where";
544 return $this->Execute($sql) != false;
547 // returns query ID if successful, otherwise false
548 function _query($sql,$inputarr)
550 $this->_errorMsg = false;
551 if (is_array($inputarr)) {
553 # bind input params with sp_executesql:
554 # see http://www.quest-pipelines.com/newsletter-v3/0402_F.htm
555 # works only with sql server 7 and newer
556 if (!is_array($sql)) $sql = $this->Prepare($sql);
560 foreach($inputarr as $v) {
567 if ($len == 0) $len = 1;
570 // NVARCHAR is max 4000 chars. Let's use NTEXT
571 $decl .= "@P$i NTEXT";
573 $decl .= "@P$i NVARCHAR($len)";
576 $params .= "@P$i=N". (strncmp($v,"'",1)==0? $v : $this->qstr($v));
577 } elseif (is_integer($v)) {
579 $params .= "@P$i=".$v;
581 $decl .= "@P$i FLOAT";
582 $params .= "@P$i=".$v;
586 $decl = $this->qstr($decl);
587 if ($this->debug) ADOConnection::outp("<font size=-1>sp_executesql N{$sql[1]},N$decl,$params</font>");
588 $rez = mssql_query("sp_executesql N{$sql[1]},N$decl,$params");
590 } elseif (is_array($sql)) {
592 $rez = mssql_execute($sql[1]);
595 $rez = mssql_query($sql,$this->_connectionID);
600 // returns true or false
603 if ($this->transCnt) $this->RollbackTrans();
604 $rez = @mssql_close($this->_connectionID);
605 $this->_connectionID = false;
609 // mssql uses a default date like Dec 30 2000 12:00AM
610 function UnixDate($v)
612 return ADORecordSet_array_mssql::UnixDate($v);
615 function UnixTimeStamp($v)
617 return ADORecordSet_array_mssql::UnixTimeStamp($v);
621 /*--------------------------------------------------------------------------------------
622 Class Name: Recordset
623 --------------------------------------------------------------------------------------*/
625 class ADORecordset_mssql extends ADORecordSet {
627 var $databaseType = "mssql";
629 var $hasFetchAssoc; // see http://phplens.com/lens/lensforum/msgs.php?id=6083
630 // _mths works only in non-localised system
632 function ADORecordset_mssql($id,$mode=false)
635 $this->hasFetchAssoc = function_exists('mssql_fetch_assoc');
637 if ($mode === false) {
638 global $ADODB_FETCH_MODE;
639 $mode = $ADODB_FETCH_MODE;
641 $this->fetchMode = $mode;
642 return $this->ADORecordSet($id,$mode);
648 GLOBAL $ADODB_COUNTRECS;
649 $this->_numOfRows = ($ADODB_COUNTRECS)? @mssql_num_rows($this->_queryID):-1;
650 $this->_numOfFields = @mssql_num_fields($this->_queryID);
654 //Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
655 // get next resultset - requires PHP 4.0.5 or later
656 function NextRecordSet()
658 if (!mssql_next_result($this->_queryID)) return false;
659 $this->_inited = false;
661 $this->_currentRow = -1;
666 /* Use associative array to get fields array */
667 function Fields($colname)
669 if ($this->fetchMode != ADODB_FETCH_NUM) return $this->fields[$colname];
671 $this->bind = array();
672 for ($i=0; $i < $this->_numOfFields; $i++) {
673 $o = $this->FetchField($i);
674 $this->bind[strtoupper($o->name)] = $i;
678 return $this->fields[$this->bind[strtoupper($colname)]];
681 /* Returns: an object containing field information.
682 Get column information in the Recordset object. fetchField() can be used in order to obtain information about
683 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
684 fetchField() is retrieved. */
686 function FetchField($fieldOffset = -1)
688 if ($fieldOffset != -1) {
689 return @mssql_fetch_field($this->_queryID, $fieldOffset);
691 else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
692 return @mssql_fetch_field($this->_queryID);
699 return @mssql_data_seek($this->_queryID, $row);
705 if ($this->EOF) return false;
707 $this->_currentRow++;
709 if ($this->fetchMode & ADODB_FETCH_ASSOC) {
710 if ($this->fetchMode & ADODB_FETCH_NUM) {
711 //ADODB_FETCH_BOTH mode
712 $this->fields = @mssql_fetch_array($this->_queryID);
715 if ($this->hasFetchAssoc) {// only for PHP 4.2.0 or later
716 $this->fields = @mssql_fetch_assoc($this->_queryID);
718 $flds = @mssql_fetch_array($this->_queryID);
719 if (is_array($flds)) {
721 foreach($flds as $k => $v) {
722 if (is_numeric($k)) continue;
725 $this->fields = $fassoc;
727 $this->fields = false;
731 if (is_array($this->fields)) {
732 if (ADODB_ASSOC_CASE == 0) {
733 foreach($this->fields as $k=>$v) {
734 $this->fields[strtolower($k)] = $v;
736 } elseif (ADODB_ASSOC_CASE == 1) {
737 foreach($this->fields as $k=>$v) {
738 $this->fields[strtoupper($k)] = $v;
743 $this->fields = @mssql_fetch_row($this->_queryID);
745 if ($this->fields) return true;
752 // INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
753 // also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
754 function _fetch($ignore_fields=false)
756 if ($this->fetchMode & ADODB_FETCH_ASSOC) {
757 if ($this->fetchMode & ADODB_FETCH_NUM) {
758 //ADODB_FETCH_BOTH mode
759 $this->fields = @mssql_fetch_array($this->_queryID);
761 if ($this->hasFetchAssoc) // only for PHP 4.2.0 or later
762 $this->fields = @mssql_fetch_assoc($this->_queryID);
764 $this->fields = @mssql_fetch_array($this->_queryID);
765 if (is_array($$this->fields)) {
767 foreach($$this->fields as $k => $v) {
768 if (is_integer($k)) continue;
771 $this->fields = $fassoc;
776 if (!$this->fields) {
777 } elseif (ADODB_ASSOC_CASE == 0) {
778 foreach($this->fields as $k=>$v) {
779 $this->fields[strtolower($k)] = $v;
781 } elseif (ADODB_ASSOC_CASE == 1) {
782 foreach($this->fields as $k=>$v) {
783 $this->fields[strtoupper($k)] = $v;
787 $this->fields = @mssql_fetch_row($this->_queryID);
789 return $this->fields;
792 /* close() only needs to be called if you are worried about using too much memory while your script
793 is running. All associated result memory for the specified result identifier will automatically be freed. */
797 $rez = mssql_free_result($this->_queryID);
798 $this->_queryID = false;
801 // mssql uses a default date like Dec 30 2000 12:00AM
802 function UnixDate($v)
804 return ADORecordSet_array_mssql::UnixDate($v);
807 function UnixTimeStamp($v)
809 return ADORecordSet_array_mssql::UnixTimeStamp($v);
815 class ADORecordSet_array_mssql extends ADORecordSet_array {
816 function ADORecordSet_array_mssql($id=-1,$mode=false)
818 $this->ADORecordSet_array($id,$mode);
821 // mssql uses a default date like Dec 30 2000 12:00AM
822 function UnixDate($v)
825 if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
827 global $ADODB_mssql_mths,$ADODB_mssql_date_order;
829 //Dec 30 2000 12:00AM
830 if ($ADODB_mssql_date_order == 'dmy') {
831 if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
832 return parent::UnixDate($v);
834 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
837 $themth = substr(strtoupper($rr[2]),0,3);
839 if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
840 return parent::UnixDate($v);
842 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
845 $themth = substr(strtoupper($rr[1]),0,3);
847 $themth = $ADODB_mssql_mths[$themth];
848 if ($themth <= 0) return false;
850 return mktime(0,0,0,$themth,$theday,$rr[3]);
853 function UnixTimeStamp($v)
856 if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
858 global $ADODB_mssql_mths,$ADODB_mssql_date_order;
860 //Dec 30 2000 12:00AM
861 if ($ADODB_mssql_date_order == 'dmy') {
862 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})|"
863 ,$v, $rr)) return parent::UnixTimeStamp($v);
864 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
867 $themth = substr(strtoupper($rr[2]),0,3);
869 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})|"
870 ,$v, $rr)) return parent::UnixTimeStamp($v);
871 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
874 $themth = substr(strtoupper($rr[1]),0,3);
877 $themth = $ADODB_mssql_mths[$themth];
878 if ($themth <= 0) return false;
880 switch (strtoupper($rr[6])) {
882 if ($rr[4]<12) $rr[4] += 12;
885 if ($rr[4]==12) $rr[4] = 0;
891 return mktime($rr[4],$rr[5],0,$themth,$theday,$rr[3]);
898 select object_name(constid) as constraint_name,
899 object_name(fkeyid) as table_name,
900 col_name(fkeyid, fkey) as column_name,
901 object_name(rkeyid) as referenced_table_name,
902 col_name(rkeyid, rkey) as referenced_column_name
904 where object_name(fkeyid) = x
905 order by constraint_name, table_name, referenced_table_name, keyno
908 select constraint_name,
911 from information_schema.key_column_usage
912 where constraint_catalog = db_name()
914 order by constraint_name, ordinal_position
916 http://www.databasejournal.com/scripts/article.php/1440551