phpbar.de logo

Mailinglisten-Archive

[php] MS SQL, ADO DB via COM und der Kampf gegen @@IDENTITY

[php] MS SQL, ADO DB via COM und der Kampf gegen @@IDENTITY

Thorsten Koch koch at infoman.de
Fre Apr 30 16:48:11 CEST 2004


Hallo Liste,

ein kleines Schmankerl zum Wochenende von meiner Seite:

Wir greifen auf einen MS SQL Server 2000 via COM-Aufrufe zu. Hierzu wird
folgende Funktion benutzt, um eine Connection zu öffnen:

function db_open(&$host)
{
  if(db_connect($host))
  {
    extract($host, EXTR_PREFIX_ALL, "db");
    $com_conn = new COM ("ADODB.Connection", NULL, DB_INTERNAL_CODING)
              or die ("COM database connection create failed.
Application is not able to start");
    $connect="Provider=sqloledb;Data Source=$db_host;Initial
Catalog=$db_db;User ID=$db_user;Password=$db_pw;";
    $com_conn->CursorLocation=3; // damit man als Parameter
affected_rows zurückgekommt?!
    @$com_conn->Open($connect);
    if($com_conn->State==0) // to-do: error bei Open noch abfangen
    {
      array_push($php_errormsg, "Verbindung zur Datenbank $db_db
momentan nicht möglich.");
      return FALSE;
    }
  }
  else return FALSE;
  return TRUE;
}

In dem Parameter $host stehen alle Informationen, die man braucht um die
Verbindung herzustellen. Das klappt auch alles wunderbar. Jetzt benutzen
wir folgende Funktion, um ein Query abzusetzen (Das Ergebnis wird im
Parameter $result an die Außenwelt zurückgeliefert).


function db_query(&$host, $query, &$result)
{
  global $php_errormsg, $com_conn, $log;
  $aff_rows=0;
  $cursor_type=3; //adOpenStatic -> Recordset wird bei Änderungen
anderer Benutzer nicht angeglichen
  $lock_type=-1; // 3?
  $exec_opt=-1;
  $result=array();

  if(db_open($host))
  {
    $db_result =  new COM('ADODB.Recordset', NULL, DB_INTERNAL_CODING);
    if(!$db_result)
    {
      array_push($php_errormsg,__LINE__." Couldn´t create new
COM(ADODB.Recordset) ");
      $return_value=-1;
    }
    else
    {
	$db_result->Open ($query, $com_conn, $cursor_type, $lock_type,
$exec_opt);
      if($db_result->State==0)
      {
        $php_errormsg=__LINE__." SQL-error: $query"; //XX
        $return_value=FALSE;
      }
      else
      {
        $num_columns = $db_result->Fields->Count();
        for ($i=0; $i < $num_columns; $i++)
        {
          $fld[$i] = $db_result->Fields($i);
          $names[$i]=$fld[$i]->name;
        }
        $rowcount = 0;
        $db_result->MoveFirst();
    	  while (!$db_result->EOF)
        {
          for ($i=0; $i < $num_columns; $i++)
          {
            $return_value[$rowcount][$i]=$fld[$i]->value;
            $return_value[$rowcount][$names[$i]]=$fld[$i]->value;
          }
          $rowcount++;            // increments rowcount
          $db_result->MoveNext();
        }
        $db_result->close();
        $db_result->Release();
        $db_result = null;
        $result=$return_value;
        $return_value=TRUE;
      }
    }
    $com_conn->close();
    $com_conn->Release();
    $com_conn = null;
  }
  else return FALSE;
  return $return_value;
}

Nun setzen wir ein Query ab, welches gleichzeitig mehrere Inserts und
Updates macht, am Ende wollen wir aber die ID eines bestimmten Inserts
zurückbekommen (Beispiel):

$query="insert into T_x_User (Name, Vorname) VALUES (N'Koch',
N'Thorsten'); declare @draftID int; SET @draftID = @@IDENTITY; insert
into T_x_Adress (UserID, Street, City) values (@@IDENTITY,
'Vaihingerstr.', 'Stuttgart'); select @draftID as Newid;";


Was wir als Recordset zurückbekommen wollen ist also eine Zelle, in der
die ID steht, die beim ersten INSERT entstanden ist. Leider liefert die
Funktion überhaupt nichts zurück, das Recordset ist schon geschlossen.

Any hints? Und bitte keine Fragen, warum wir nicht die mssql-Funktionen
verwenden und warum wir COM-Aufrufe verwenden etc. Das steht hier nicht
zur Debatte und hat diverse Gründe :-)


-- 
Mit freundlichen Grüßen

 Thorsten Koch                         Tel:  +49 711 67971-662
 Informationsmanagement GmbH           Fax:  +49 711 67971-10
 Vaihinger Str. 169                    http://www.infoman-systeme.de
 D-70567 Stuttgart                     mailto:thorsten.koch at infoman.de 
***********************************************************************




php::bar PHP Wiki   -   Listenarchive