2013-05-22 3 views
1

Je tente d'exécuter une requête sur une base de données MSSQL et de renvoyer l'ID d'insertion en utilisant PHP. Auparavant, j'avais été en utilisant le code suivant pour ce qui a bien fonctionné:Comment utiliser PHP pour renvoyer le dernier ID inséré sur une table MSSQL avec Triggers installés

$q = "INSERT INTO Pricing (Products_idProducts,FromQty,ToQty,Price) VALUES((?),(?),(?),(?)); SELECT IDENT_CURRENT('Pricing') AS 'id';"; 
$params = array($_POST['idProduct'], $_POST['Pricing-FromQty'], $_POST['Pricing-ToQty'], $_POST['Pricing-Price']); 
$r = sqlsrv_query($db, $q, $params); 
sqlsrv_next_result($r); 
sqlsrv_fetch($r); 
$LastID = sqlsrv_get_field($r, 0); 

Cependant, en raison des exigences d'intégration, nous avons ajouté un déclencheur à la table des prix qui copie les données à une table temporaire dans une autre base de données chaque fois une requête INSERT est exécutée. Ce genre de change l'ordre des opérations. D'après ce que je peux dire, ce qui suit se produit:

Web App -> INSERT into Pricing Table 
Trigger -> INSERT into Temp Table 
Web App -> Get ID 

J'avais déjà été en utilisant SCOPE_IDENTITY, il était donc logique que le déclencheur a été le dernier ID écrasant d'insertion. Mais quand j'ai compris cela, je suis passé à IDENT_CURRENT ('Prix') pour être plus explicite dans ma demande. Cependant, il renvoie toujours une valeur nulle.

Je devrais ajouter que si nous désactivons le déclencheur, ce code fonctionne parfaitement.

Est-il possible de renvoyer le dernier ID inséré sur une table qui contient des déclencheurs?

Merci beaucoup pour vos conseils et vos idées.

EDIT: Voici le déclencheur:

IF EXISTS (SELECT 1 FROM inserted cp) 
BEGIN 
     INSERT INTO [ProductManager].._PRICESTAGING ([ITEMNUM],[QFR],[QTO],[PRICE]) 
     SELECT PartNumber,[FromQty],[ToQty],Price 
     FROM inserted cp 
END 

EDIT: Résolu! Eh bien, je ne comprends toujours pas exactement pourquoi, mais le problème semble avoir été causé par une étrange combinaison des deux en utilisant un déclencheur, et en essayant de combiner les requêtes ensemble. Apparemment, si une table a un déclencheur, vous devez exécuter les requêtes séparément. Voici ce qui a finalement travaillé:

$q = "INSERT INTO Pricing (Products_idProducts,FromQty,ToQty,Price) VALUES((?),(?),(?),(?));"; 
$params = array($_POST['idProduct'], $_POST['Pricing-FromQty'], $_POST['Pricing-ToQty'], $_POST['Pricing-Price']); 
$r = sqlsrv_query($db, $q, $params); 

// bypass trigger nonsense 
$q = "SELECT IDENT_CURRENT('Pricing') AS 'id';"; 
$r = sqlsrv_query($db, $q); 
$LastID = sqlsrv_fetch_array($r); 
$LastID = $LastID['id']; 
+0

Cr @ zy. Sachant que c'est la moitié de la bataille. – granadaCoder

+0

Je pose la question ... parce que c'est une bonne idée pour les futurs lecteurs sur les lignes séparées. – granadaCoder

Répondre

0

Essayez

http://msdn.microsoft.com/en-us/library/ms175098.aspx

IDENT_CURRENT

Il est un autre des "saveurs" ...

IDENT_CURRENT ('MyTableName')

EDIT ---------

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Vegetable]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) 
    BEGIN 
     DROP TABLE [dbo].[Vegetable] 
    END 
GO 

CREATE TABLE [dbo].[Vegetable] (
     VegetableKey   int IDENTITY (1001 , 1) not null 
    , VegetableName  varchar(64) not null 
) 
GO 


ALTER TABLE dbo.Vegetable ADD CONSTRAINT PK_Vegetable_VegetableKey 
PRIMARY KEY CLUSTERED (VegetableKey) 
GO 


ALTER TABLE dbo.Vegetable ADD CONSTRAINT CK_Vegetable_VegetableName_UNIQUE 
UNIQUE (VegetableName) 
GO 


GRANT SELECT , INSERT, UPDATE, DELETE ON [dbo].[Vegetable] TO public 
GO 








if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[FoodItem]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) 
    BEGIN 
     DROP TABLE [dbo].[FoodItem] 
    END 
GO 

CREATE TABLE [dbo].[FoodItem] (
     FoodItemKey   int IDENTITY (2001 , 1) not null 
    , FoodItemName  varchar(64) not null 
) 
GO 


ALTER TABLE dbo.FoodItem ADD CONSTRAINT PK_FoodItem_FoodItemKey 
PRIMARY KEY CLUSTERED (FoodItemKey) 
GO 


ALTER TABLE dbo.FoodItem ADD CONSTRAINT CK_FoodItem_FoodItemName_UNIQUE 
UNIQUE (FoodItemName) 
GO 


GRANT SELECT , INSERT, UPDATE, DELETE ON [dbo].[FoodItem] TO public 
GO 










CREATE TRIGGER CopyVegetableToFoodItemTrigger on dbo.Vegetable 
FOR INSERT , UPDATE AS 

INSERT into dbo.FoodItem (FoodItemName) 
Select i.VegetableName from 
inserted i 
where not exists (select null from dbo.FoodItem innerRealTable where innerRealTable.FoodItemName = i.VegetableName) 

GO 


declare @MyIdentity int 

INSERT INTO dbo.Vegetable (VegetableName) select 'Pumpkin' 
select @MyIdentity = IDENT_CURRENT('[dbo].[Vegetable]') 
print @MyIdentity 


INSERT INTO dbo.Vegetable (VegetableName) select 'Tomato' 
select @MyIdentity = IDENT_CURRENT(N'[dbo].[Vegetable]') 
print @MyIdentity 


select * from dbo.Vegetable 

select * from dbo.FoodItem 
+0

Oui, vous verrez dans mon exemple de code que j'utilise actuellement IDENT_CURRENT ('Pricing'). Il ne renvoie rien, lorsque le déclencheur est actif sur cette table. Y a-t-il une méthode alternative? Merci. – Typel

+0

C'est bizarre, parce que le gros problème avec cette fonction était qu'elle n'était pas affectée par les déclencheurs. Voir le code de démonstration ici: http://msdn.microsoft.com/en-us/library/aa933217(v=sql.80).aspx – granadaCoder

+0

Oui, très étrange.Ce matin, je l'ai effectivement testé sans que la gâchette ne soit activée à nouveau pour être certain, et cela a fonctionné parfaitement. Puis, dès que j'ai activé le déclencheur, il cesse de fonctionner. Peut-être qu'il y a quelque chose dans le déclencheur qui gâche ident_current? Est-ce que c'est possible? Hmm. – Typel

0

Il est un temps très long depuis que je devais travailler avec MSSQL, mais je l'habitude d'utiliser cette ...

SELECT [email protected]@IDENTITY 

Est-ce que le travail encore?

+0

Malheureusement, j'ai essayé cela aussi et il a le même problème. SCOPE_IDENTITY, @@ IDENTITY et IDENT_CURRENT ('tablename') apparaissent tous les mains vides lorsque ce déclencheur est actif. J'espérais qu'il y avait une autre façon d'obtenir l'identifiant. Merci quand même. – Typel

Questions connexes