[英]How to use PHP to return the last inserted ID on an MSSQL table with Triggers installed
I am attempting to run a query on an MSSQL database and return the insert ID using PHP. 我试图在MSSQL数据库上运行查询,并使用PHP返回插入ID。 Previously, I had been using the following code for this, which worked fine:
以前,我一直在使用以下代码来正常工作:
$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 );
However, due to integration requirements, we added a trigger to the Pricing table that copies the data to a temporary table in another database whenever an INSERT query is run. 但是,由于集成要求,我们在定价表中添加了一个触发器,该触发器在每次运行INSERT查询时将数据复制到另一个数据库中的临时表中。 This kind of changes the order of operations.
这种改变操作的顺序。 From what I can tell, the following is occurring:
据我所知,正在发生以下情况:
Web App -> INSERT into Pricing Table
Trigger -> INSERT into Temp Table
Web App -> Get ID
I had previously been using SCOPE_IDENTITY, so it made sense that the trigger was overwriting the last insert ID. 我以前一直在使用SCOPE_IDENTITY,因此触发器覆盖了最后一个插入ID是有意义的。 But when I figured this out, I switched to IDENT_CURRENT('Pricing') to be more explicit in my request.
但是,当我弄清楚这一点时,我切换到IDENT_CURRENT('Pricing')以便在请求中更加明确。 However, it is still returning a null value.
但是,它仍返回空值。
I should add that if we disable the trigger, this code works perfectly. 我应该补充一点,如果我们禁用触发器,则此代码将完美运行。
Is there any way to return the last inserted ID on a table that has triggers on it? 有什么方法可以返回具有触发器的表上最后插入的ID?
Thanks so much for any advice or ideas. 非常感谢您的任何建议或想法。
EDIT: Here is the Trigger: 编辑:这是触发器:
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: Solved! 编辑:解决了!
Well, I still don't understand exactly why, but the problem seems to have been caused by a weird combination of both using a trigger, and trying to combine the queries together. 好吧,我仍然不清楚为什么,但是问题似乎是由使用触发器和尝试将查询组合在一起的奇怪组合造成的。 Apparently, if a table has a trigger on it, you need to run queries separately.
显然,如果表上有触发器,则需要单独运行查询。 Here is what eventually worked:
这是最终有效的方法:
$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'];
Try 尝试
http://msdn.microsoft.com/en-us/library/ms175098.aspx http://msdn.microsoft.com/en-us/library/ms175098.aspx
IDENT_CURRENT IDENT_CURRENT
It's another one of the "flavors"... 这是另一种“味道” ...
IDENT_CURRENT( 'MyTableName' ) 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
It's a very long time since I had to work with MSSQL, but I used to use this... 自从我不得不使用MSSQL以来已经很长时间了,但是我以前经常使用它。
SELECT LAST_INSERT_ID=@@IDENTITY
Does that still work? 那还行吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.