3 V4.20 22 Feb 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 //----------------------------------------------------------------
36 // has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
37 if (ADODB_PHPVER
>= 0x4300) {
38 // docs say 4.2.0, but testing shows only since 4.3.0 does it work!
39 ini_set('mssql.datetimeconvert',0);
41 global $ADODB_mssql_mths; // array, months must be upper-case
44 $ADODB_mssql_date_order = 'mdy';
45 $ADODB_mssql_mths = array(
46 'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
47 'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
50 //---------------------------------------------------------------------------
51 // Call this to autoset $ADODB_mssql_date_order at the beginning of your code,
52 // just after you connect to the database. Supports mdy and dmy only.
53 // Not required for PHP 4.2.0 and above.
54 function AutoDetect_MSSQL_Date_Order($conn)
56 global $ADODB_mssql_date_order;
57 $adate = $conn->GetOne('select getdate()');
62 //ADOConnection::outp( "MSSQL: YYYY-MM-DD date format not supported currently");
64 $ADODB_mssql_date_order = 'dmy';
66 $ADODB_mssql_date_order = 'mdy';
70 class ADODB_mssql
extends ADOConnection
{
71 var $databaseType = "mssql";
72 var $dataProvider = "mssql";
73 var $replaceQuote = "''"; // string to use to replace quotes
74 var $fmtDate = "'Y-m-d'";
75 var $fmtTimeStamp = "'Y-m-d h:i:sA'";
76 var $hasInsertID = true;
77 var $substr = "substring";
79 var $upperCase = 'upper';
80 var $hasAffectedRows = true;
81 var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
82 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'))";
83 var $metaColumnsSQL = # xtype==61 is datetime
84 "select c.name,t.name,c.length,
85 (case when c.xusertype=61 then 0 else c.xprec end),
86 (case when c.xusertype=61 then 0 else c.xscale end)
87 from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
88 var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
90 var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
91 var $sysTimeStamp = 'GetDate()';
93 var $maxParameterLen = 4000;
94 var $arrayClass = 'ADORecordSet_array_mssql';
95 var $uniqueSort = true;
96 var $leftOuter = '*=';
97 var $rightOuter = '=*';
98 var $ansiOuter = true; // for mssql7 or later
99 var $poorAffectedRows = true;
100 var $identitySQL = 'select @@IDENTITY'; // 'select SCOPE_IDENTITY'; # for mssql 2000
101 var $uniqueOrderBy = true;
102 var $_bindInputArray = true;
105 function ADODB_mssql()
107 $this->_has_mssql_init
= (strnatcmp(PHP_VERSION
,'4.1.0')>=0);
110 function ServerInfo()
112 global $ADODB_FETCH_MODE;
114 $stmt = $this->PrepareSP('sp_server_info');
116 if ($this->fetchMode
=== false) {
117 $savem = $ADODB_FETCH_MODE;
118 $ADODB_FETCH_MODE = ADODB_FETCH_NUM
;
120 $savem = $this->SetFetchMode(ADODB_FETCH_NUM
);
123 $this->Parameter($stmt,$val,'attribute_id');
124 $row = $this->GetRow($stmt);
126 //$row = $this->GetRow("execute sp_server_info 2");
128 if ($this->fetchMode
=== false) {
129 $ADODB_FETCH_MODE = $savem;
131 $this->SetFetchMode($savem);
133 $arr['description'] = $row[2];
134 $arr['version'] = ADOConnection
::_findvers($arr['description']);
138 function IfNull( $field, $ifNull )
140 return " ISNULL($field, $ifNull) "; // if MS SQL Server
146 // Returns the last IDENTITY value inserted into an IDENTITY column in
147 // the same scope. A scope is a module -- a stored procedure, trigger,
148 // function, or batch. Thus, two statements are in the same scope if
149 // they are in the same stored procedure, function, or batch.
150 return $this->GetOne($this->identitySQL
);
153 function _affectedrows()
155 return $this->GetOne('select @@rowcount');
158 var $_dropSeqSQL = "drop table %s";
160 function CreateSequence($seq='adodbseq',$start=1)
163 $this->Execute("create table $seq (id float(53))");
164 $ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
166 $this->Execute('ROLLBACK TRANSACTION adodbseq');
169 $this->Execute('COMMIT TRANSACTION adodbseq');
173 function GenID($seq='adodbseq',$start=1)
176 $this->Execute('BEGIN TRANSACTION adodbseq');
177 $ok = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
179 $this->Execute("create table $seq (id float(53))");
180 $ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
182 $this->Execute('ROLLBACK TRANSACTION adodbseq');
185 $this->Execute('COMMIT TRANSACTION adodbseq');
188 $num = $this->GetOne("select id from $seq");
189 $this->Execute('COMMIT TRANSACTION adodbseq');
192 // in old implementation, pre 1.90, we returned GUID...
193 //return $this->GetOne("SELECT CONVERT(varchar(255), NEWID()) AS 'Char'");
197 function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
199 if ($nrows > 0 && $offset <= 0) {
201 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop
." $nrows ",$sql);
202 $rs =& $this->Execute($sql,$inputarr);
204 $rs =& ADOConnection
::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
210 // Format date column in sql string given an input format that understands Y M D
211 function SQLDate($fmt, $col=false)
213 if (!$col) $col = $this->sysTimeStamp
;
217 for ($i=0; $i < $len; $i++
) {
223 $s .= "datename(yyyy,$col)";
226 $s .= "convert(char(3),$col,0)";
229 $s .= "replace(str(month($col),2),' ','0')";
233 $s .= "datename(quarter,$col)";
237 $s .= "replace(str(day($col),2),' ','0')";
240 $s .= "substring(convert(char(14),$col,0),13,2)";
244 $s .= "replace(str(datepart(hh,$col),2),' ','0')";
248 $s .= "replace(str(datepart(mi,$col),2),' ','0')";
251 $s .= "replace(str(datepart(ss,$col),2),' ','0')";
255 $s .= "substring(convert(char(19),$col,0),18,2)";
261 $ch = substr($fmt,$i,1);
263 $s .= $this->qstr($ch);
271 function BeginTrans()
273 if ($this->transOff
) return true;
274 $this->transCnt +
= 1;
275 $this->Execute('BEGIN TRAN');
279 function CommitTrans($ok=true)
281 if ($this->transOff
) return true;
282 if (!$ok) return $this->RollbackTrans();
283 if ($this->transCnt
) $this->transCnt
-= 1;
284 $this->Execute('COMMIT TRAN');
287 function RollbackTrans()
289 if ($this->transOff
) return true;
290 if ($this->transCnt
) $this->transCnt
-= 1;
291 $this->Execute('ROLLBACK TRAN');
299 $this->RowLock('table1,table2','table1.id=33 and table2.id=table1.id'); # lock row 33 for both tables
301 # some operation on both tables table1 and table2
303 $this->CommitTrans();
305 See http://www.swynk.com/friends/achigrik/SQL70Locks.asp
307 function RowLock($tables,$where)
309 if (!$this->transCnt
) $this->BeginTrans();
310 return $this->GetOne("select top 1 null as ignore from $tables with (ROWLOCK,HOLDLOCK) where $where");
313 function MetaForeignKeys($table, $owner=false, $upper=false)
315 global $ADODB_FETCH_MODE;
317 $save = $ADODB_FETCH_MODE;
318 $ADODB_FETCH_MODE = ADODB_FETCH_NUM
;
319 $table = $this->qstr(strtoupper($table));
322 "select object_name(constid) as constraint_name,
323 col_name(fkeyid, fkey) as column_name,
324 object_name(rkeyid) as referenced_table_name,
325 col_name(rkeyid, rkey) as referenced_column_name
327 where upper(object_name(fkeyid)) = $table
328 order by constraint_name, referenced_table_name, keyno";
330 $constraints =& $this->GetArray($sql);
332 $ADODB_FETCH_MODE = $save;
335 foreach($constraints as $constr) {
337 $arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
339 if (!$arr) return false;
343 foreach($arr as $k => $v) {
344 foreach($v as $a => $b) {
345 if ($upper) $a = strtoupper($a);
352 //From: Fernando Moreira <FMoreira@imediata.pt>
353 function MetaDatabases()
355 if(@mssql_select_db
("master")) {
356 $qry=$this->metaDatabasesSQL
;
357 if($rs=@mssql_query
($qry)){
359 while($tmpAr=@mssql_fetch_row
($rs))
361 @mssql_select_db
($this->databaseName
);
367 @mssql_select_db
($this->databaseName
);
374 // "Stein-Aksel Basma" <basma@accelero.no>
375 // tested with MSSQL 2000
376 function MetaPrimaryKeys($table)
378 $sql = "select k.column_name from information_schema.key_column_usage k,
379 information_schema.table_constraints tc
380 where tc.constraint_name = k.constraint_name and tc.constraint_type =
381 'PRIMARY KEY' and k.table_name = '$table'";
383 $a = $this->GetCol($sql);
384 if ($a && sizeof($a)>0) return $a;
389 function &MetaTables($ttype=false,$showSchema=false,$mask=false)
392 $save = $this->metaTablesSQL
;
393 $mask = $this->qstr(($mask));
394 $this->metaTablesSQL
.= " AND name like $mask";
396 $ret =& ADOConnection
::MetaTables($ttype,$showSchema);
399 $this->metaTablesSQL
= $save;
404 function SelectDB($dbName)
406 $this->databaseName
= $dbName;
407 if ($this->_connectionID
) {
408 return @mssql_select_db
($dbName);
415 if (empty($this->_errorMsg
)){
416 $this->_errorMsg
= mssql_get_last_message();
418 return $this->_errorMsg
;
423 if ($this->_logsql
&& $this->_errorCode
!== false) return $this->_errorCode
;
424 if (empty($this->_errorMsg
)) {
425 $this->_errorMsg
= mssql_get_last_message();
427 $id = @mssql_query
("select @@ERROR",$this->_connectionID
);
428 if (!$id) return false;
429 $arr = mssql_fetch_array($id);
430 @mssql_free_result
($id);
431 if (is_array($arr)) return $arr[0];
435 // returns true or false
436 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
438 if (!function_exists('mssql_pconnect')) return false;
439 $this->_connectionID
= mssql_connect($argHostname,$argUsername,$argPassword);
440 if ($this->_connectionID
=== false) return false;
441 if ($argDatabasename) return $this->SelectDB($argDatabasename);
446 // returns true or false
447 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
449 if (!function_exists('mssql_pconnect')) return false;
450 $this->_connectionID
= mssql_pconnect($argHostname,$argUsername,$argPassword);
451 if ($this->_connectionID
=== false) return false;
453 // persistent connections can forget to rollback on crash, so we do it here.
454 if ($this->autoRollback
) {
455 $cnt = $this->GetOne('select @@TRANCOUNT');
456 while (--$cnt >= 0) $this->Execute('ROLLBACK TRAN');
458 if ($argDatabasename) return $this->SelectDB($argDatabasename);
462 function Prepare($sql)
464 $sqlarr = explode('?',$sql);
465 if (sizeof($sqlarr) <= 1) return $sql;
467 for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++
) {
468 $sql2 .= '@P'.($i-1) . $sqlarr[$i];
470 return array($sql,$this->qstr($sql2),$max);
473 function PrepareSP($sql)
475 if (!$this->_has_mssql_init
) {
476 ADOConnection
::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
479 $stmt = mssql_init($sql,$this->_connectionID
);
480 if (!$stmt) return $sql;
481 return array($sql,$stmt);
486 $stmt = $db->PrepareSP('SP_RUNSOMETHING'); -- takes 2 params, @myid and @group
488 # note that the parameter does not have @ in front!
489 $db->Parameter($stmt,$id,'myid');
490 $db->Parameter($stmt,$group,'group',false,64);
493 @param $stmt Statement returned by Prepare() or PrepareSP().
494 @param $var PHP variable to bind to. Can set to null (for isNull support).
495 @param $name Name of stored procedure variable name to bind to.
496 @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
497 @param [$maxLen] Holds an maximum length of the variable.
498 @param [$type] The data type of $var. Legal values depend on driver.
500 See mssql_bind documentation at php.net.
502 function Parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=4000, $type=false)
504 if (!$this->_has_mssql_init
) {
505 ADOConnection
::outp( "Parameter: mssql_bind only available since PHP 4.1.0");
509 $isNull = is_null($var); // php 4.0.4 and above...
512 switch(gettype($var)) {
514 case 'string': $type = SQLCHAR
; break;
515 case 'double': $type = SQLFLT8
; break;
516 case 'integer': $type = SQLINT4
; break;
517 case 'boolean': $type = SQLINT1
; break; # SQLBIT not supported in 4.1.0
521 $prefix = ($isOutput) ?
'Out' : 'In';
522 $ztype = (empty($type)) ?
'false' : $type;
523 ADOConnection
::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
526 See http://phplens.com/lens/lensforum/msgs.php?id=7231
528 RETVAL is HARD CODED into php_mssql extension:
529 The return value (a long integer value) is treated like a special OUTPUT parameter,
530 called "RETVAL" (without the @). See the example at mssql_execute to
531 see how it works. - type: one of this new supported PHP constants.
532 SQLTEXT, SQLVARCHAR,SQLCHAR, SQLINT1,SQLINT2, SQLINT4, SQLBIT,SQLFLT8
534 if ($name !== 'RETVAL') $name = '@'.$name;
535 return mssql_bind($stmt[1], $name, $var, $type, $isOutput, $isNull, $maxLen);
539 Unfortunately, it appears that mssql cannot handle varbinary > 255 chars
540 So all your blobs must be of type "image".
542 Remember to set in php.ini the following...
544 ; Valid range 0 - 2147483647. Default = 4096.
545 mssql.textlimit = 0 ; zero to pass through
547 ; Valid range 0 - 2147483647. Default = 4096.
548 mssql.textsize = 0 ; zero to pass through
550 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
552 $sql = "UPDATE $table SET $column=0x".bin2hex($val)." WHERE $where";
553 return $this->Execute($sql) != false;
556 // returns query ID if successful, otherwise false
557 function _query($sql,$inputarr)
559 $this->_errorMsg
= false;
560 if (is_array($inputarr)) {
562 # bind input params with sp_executesql:
563 # see http://www.quest-pipelines.com/newsletter-v3/0402_F.htm
564 # works only with sql server 7 and newer
565 if (!is_array($sql)) $sql = $this->Prepare($sql);
569 foreach($inputarr as $v) {
576 if ($len == 0) $len = 1;
579 // NVARCHAR is max 4000 chars. Let's use NTEXT
580 $decl .= "@P$i NTEXT";
582 $decl .= "@P$i NVARCHAR($len)";
585 $params .= "@P$i=N". (strncmp($v,"'",1)==0?
$v : $this->qstr($v));
586 } else if (is_integer($v)) {
588 $params .= "@P$i=".$v;
590 $decl .= "@P$i FLOAT";
591 $params .= "@P$i=".$v;
595 $decl = $this->qstr($decl);
596 if ($this->debug
) ADOConnection
::outp("<font size=-1>sp_executesql N{$sql[1]},N$decl,$params</font>");
597 $rez = mssql_query("sp_executesql N{$sql[1]},N$decl,$params");
599 } else if (is_array($sql)) {
601 $rez = mssql_execute($sql[1]);
604 $rez = mssql_query($sql,$this->_connectionID
);
609 // returns true or false
612 if ($this->transCnt
) $this->RollbackTrans();
613 $rez = @mssql_close
($this->_connectionID
);
614 $this->_connectionID
= false;
618 // mssql uses a default date like Dec 30 2000 12:00AM
619 function UnixDate($v)
621 return ADORecordSet_array_mssql
::UnixDate($v);
624 function UnixTimeStamp($v)
626 return ADORecordSet_array_mssql
::UnixTimeStamp($v);
630 /*--------------------------------------------------------------------------------------
631 Class Name: Recordset
632 --------------------------------------------------------------------------------------*/
634 class ADORecordset_mssql
extends ADORecordSet
{
636 var $databaseType = "mssql";
638 var $hasFetchAssoc; // see http://phplens.com/lens/lensforum/msgs.php?id=6083
639 // _mths works only in non-localised system
641 function ADORecordset_mssql($id,$mode=false)
644 $this->hasFetchAssoc
= function_exists('mssql_fetch_assoc');
646 if ($mode === false) {
647 global $ADODB_FETCH_MODE;
648 $mode = $ADODB_FETCH_MODE;
650 $this->fetchMode
= $mode;
651 return $this->ADORecordSet($id,$mode);
657 GLOBAL $ADODB_COUNTRECS;
658 $this->_numOfRows
= ($ADODB_COUNTRECS)? @mssql_num_rows
($this->_queryID
):-1;
659 $this->_numOfFields
= @mssql_num_fields
($this->_queryID
);
663 //Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
664 // get next resultset - requires PHP 4.0.5 or later
665 function NextRecordSet()
667 if (!mssql_next_result($this->_queryID
)) return false;
668 $this->_inited
= false;
670 $this->_currentRow
= -1;
675 /* Use associative array to get fields array */
676 function Fields($colname)
678 if ($this->fetchMode
!= ADODB_FETCH_NUM
) return $this->fields
[$colname];
680 $this->bind
= array();
681 for ($i=0; $i < $this->_numOfFields
; $i++
) {
682 $o = $this->FetchField($i);
683 $this->bind
[strtoupper($o->name
)] = $i;
687 return $this->fields
[$this->bind
[strtoupper($colname)]];
690 /* Returns: an object containing field information.
691 Get column information in the Recordset object. fetchField() can be used in order to obtain information about
692 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
693 fetchField() is retrieved. */
695 function FetchField($fieldOffset = -1)
697 if ($fieldOffset != -1) {
698 return @mssql_fetch_field
($this->_queryID
, $fieldOffset);
700 else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
701 return @mssql_fetch_field
($this->_queryID
);
708 return @mssql_data_seek
($this->_queryID
, $row);
714 if ($this->EOF
) return false;
716 $this->_currentRow++
;
718 if ($this->fetchMode
& ADODB_FETCH_ASSOC
) {
719 if ($this->fetchMode
& ADODB_FETCH_NUM
) {
720 //ADODB_FETCH_BOTH mode
721 $this->fields
= @mssql_fetch_array
($this->_queryID
);
724 if ($this->hasFetchAssoc
) {// only for PHP 4.2.0 or later
725 $this->fields
= @mssql_fetch_assoc
($this->_queryID
);
727 $flds = @mssql_fetch_array
($this->_queryID
);
728 if (is_array($flds)) {
730 foreach($flds as $k => $v) {
731 if (is_numeric($k)) continue;
734 $this->fields
= $fassoc;
736 $this->fields
= false;
740 if (is_array($this->fields
)) {
741 if (ADODB_ASSOC_CASE
== 0) {
742 foreach($this->fields
as $k=>$v) {
743 $this->fields
[strtolower($k)] = $v;
745 } else if (ADODB_ASSOC_CASE
== 1) {
746 foreach($this->fields
as $k=>$v) {
747 $this->fields
[strtoupper($k)] = $v;
752 $this->fields
= @mssql_fetch_row
($this->_queryID
);
754 if ($this->fields
) return true;
761 // INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
762 // also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
763 function _fetch($ignore_fields=false)
765 if ($this->fetchMode
& ADODB_FETCH_ASSOC
) {
766 if ($this->fetchMode
& ADODB_FETCH_NUM
) {
767 //ADODB_FETCH_BOTH mode
768 $this->fields
= @mssql_fetch_array
($this->_queryID
);
770 if ($this->hasFetchAssoc
) // only for PHP 4.2.0 or later
771 $this->fields
= @mssql_fetch_assoc
($this->_queryID
);
773 $this->fields
= @mssql_fetch_array
($this->_queryID
);
774 if (is_array($
$this->fields
)) {
776 foreach($
$this->fields
as $k => $v) {
777 if (is_integer($k)) continue;
780 $this->fields
= $fassoc;
785 if (!$this->fields
) {
786 } else if (ADODB_ASSOC_CASE
== 0) {
787 foreach($this->fields
as $k=>$v) {
788 $this->fields
[strtolower($k)] = $v;
790 } else if (ADODB_ASSOC_CASE
== 1) {
791 foreach($this->fields
as $k=>$v) {
792 $this->fields
[strtoupper($k)] = $v;
796 $this->fields
= @mssql_fetch_row
($this->_queryID
);
798 return $this->fields
;
801 /* close() only needs to be called if you are worried about using too much memory while your script
802 is running. All associated result memory for the specified result identifier will automatically be freed. */
806 $rez = mssql_free_result($this->_queryID
);
807 $this->_queryID
= false;
810 // mssql uses a default date like Dec 30 2000 12:00AM
811 function UnixDate($v)
813 return ADORecordSet_array_mssql
::UnixDate($v);
816 function UnixTimeStamp($v)
818 return ADORecordSet_array_mssql
::UnixTimeStamp($v);
824 class ADORecordSet_array_mssql
extends ADORecordSet_array
{
825 function ADORecordSet_array_mssql($id=-1,$mode=false)
827 $this->ADORecordSet_array($id,$mode);
830 // mssql uses a default date like Dec 30 2000 12:00AM
831 function UnixDate($v)
834 if (is_numeric(substr($v,0,1)) && ADODB_PHPVER
>= 0x4200) return parent
::UnixDate($v);
836 global $ADODB_mssql_mths,$ADODB_mssql_date_order;
838 //Dec 30 2000 12:00AM
839 if ($ADODB_mssql_date_order == 'dmy') {
840 if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
841 return parent
::UnixDate($v);
843 if ($rr[3] <= TIMESTAMP_FIRST_YEAR
) return 0;
846 $themth = substr(strtoupper($rr[2]),0,3);
848 if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
849 return parent
::UnixDate($v);
851 if ($rr[3] <= TIMESTAMP_FIRST_YEAR
) return 0;
854 $themth = substr(strtoupper($rr[1]),0,3);
856 $themth = $ADODB_mssql_mths[$themth];
857 if ($themth <= 0) return false;
859 return mktime(0,0,0,$themth,$theday,$rr[3]);
862 function UnixTimeStamp($v)
865 if (is_numeric(substr($v,0,1)) && ADODB_PHPVER
>= 0x4200) return parent
::UnixTimeStamp($v);
867 global $ADODB_mssql_mths,$ADODB_mssql_date_order;
869 //Dec 30 2000 12:00AM
870 if ($ADODB_mssql_date_order == 'dmy') {
871 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})|"
872 ,$v, $rr)) return parent
::UnixTimeStamp($v);
873 if ($rr[3] <= TIMESTAMP_FIRST_YEAR
) return 0;
876 $themth = substr(strtoupper($rr[2]),0,3);
878 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})|"
879 ,$v, $rr)) return parent
::UnixTimeStamp($v);
880 if ($rr[3] <= TIMESTAMP_FIRST_YEAR
) return 0;
883 $themth = substr(strtoupper($rr[1]),0,3);
886 $themth = $ADODB_mssql_mths[$themth];
887 if ($themth <= 0) return false;
889 switch (strtoupper($rr[6])) {
891 if ($rr[4]<12) $rr[4] +
= 12;
894 if ($rr[4]==12) $rr[4] = 0;
900 return mktime($rr[4],$rr[5],0,$themth,$theday,$rr[3]);
907 select object_name(constid) as constraint_name,
908 object_name(fkeyid) as table_name,
909 col_name(fkeyid, fkey) as column_name,
910 object_name(rkeyid) as referenced_table_name,
911 col_name(rkeyid, rkey) as referenced_column_name
913 where object_name(fkeyid) = x
914 order by constraint_name, table_name, referenced_table_name, keyno
917 select constraint_name,
920 from information_schema.key_column_usage
921 where constraint_catalog = db_name()
923 order by constraint_name, ordinal_position
925 http://www.databasejournal.com/scripts/article.php/1440551