插入带有主键和scope_identity的语句

时间:2014-01-17 17:17:35

标签: php sql sql-server-2008 pdo

我想获取最新记录的主键(auto_increment),以将其用作另一个表中的外键。当我使用SCOPE_IDENTITY()作为pdo参数时,我收到错误:

  

调用未定义的函数SCOPE_IDENTITY()。

当我将它用作直接值时,语句总是回滚。

我的代码是否正确?

if (empty($errors)) {
    $sqlconnection = new SqlConnection();

    $conn = $sqlconnection->db_connect();

    if ($conn) {
        if (sqlsrv_begin_transaction($conn) === false ) {
            $errors[] = "Cant start transaction.";
        } else {
            // Query1
            $query1 = "INSERT INTO [RC.table1] (terminname, datum) VALUES (?, ?)";
            $params1 = array($eventname, $eventdate);
            $stmt1 = sqlsrv_query($conn, $query1, $params1);

            //Query2
            $query2 = "INSERT INTO [RC.table2] (appointment_id, mandant_id) VALUES ((SELECT SCOPE_IDENTITY()), ?)";
            $params2 = array($_SESSION['mandant_id']);
            $stmt2 = sqlsrv_query($conn, $query2, $params2);

            if($stmt1 && $stmt2) {
                 sqlsrv_commit( $conn );
                 echo "Transaction committed.<br />";
            } else {
                 sqlsrv_rollback( $conn );
                 echo "Transaction rolled back.<br />";
            }
        }
    } else {
        $errors[] = "Cant connect to database.";
    }
}

3 个答案:

答案 0 :(得分:1)

尝试此解决方案:替换

    $query2 = "INSERT INTO [RC.table2] (appointment_id, mandant_id) VALUES ((SELECT SCOPE_IDENTITY()), ?)";

用这个:

    $query2 = "DECLARE @LastID INT; SET @LastID = SCOPE_IDENTITY(); INSERT INTO [RC.table2] (appointment_id, mandant_id) VALUES (@LastID, ?)";

此外,对于@LastID变量定义(DECLARE @LastID INT),请使用与appointment_id列的数据类型相同的数据类型。在此示例中,我假设@LastID的类型为INT

修改:您可以使用stored procedure创建以下TRY ... CATCH

CREATE PROCEDURE dbo.Insert_Table1Table2 
(
    @terminname NVARCHAR(50), 
    @datum DATE,
    @mandant_id INT 
)
AS
BEGIN
    BEGIN TRANSACTION;

    BEGIN TRY
        INSERT INTO [RC.table1] (terminname, datum) VALUES (@terminname, @datum)
        DECLARE @appointment_id INT; 
        SET @appointment_id = SCOPE_IDENTITY(); 
        INSERT INTO [RC.table2] (appointment_id, mandant_id) VALUES (@appointment_id, @mandant_id)
    END TRY
    BEGIN CATCH
    SELECT 
        DECLARE @ErrorMessage NVARCHAR(2048);
        SET @ErrorMessage = ERROR_MESSAGE();
        RAISERROR(@ErrorMessage, 16, 1)

        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION;
    END CATCH;

    IF @@TRANCOUNT > 0
        COMMIT TRANSACTION;
END

注意:您应该更换每种类型和最大值。长度适当的类型和长度。

答案 1 :(得分:0)

BEGIN TRAN T1;
INSERT INTO [RC.table1] (terminname, datum) VALUES ('alibaba', '24.02.2014');
BEGIN TRAN T22
INSERT INTO [RC.table2] (appointment_id, mandant_id) VALUES ((SELECT SCOPE_IDENTITY()), '0200')
COMMIT TRAN T1;
COMMIT TRAN T2;

在工作室中完美运作。不知道,为什么我不能在php交易中获得身份。

答案 2 :(得分:-1)

顺便说一句,虽然该代码可能有效,但我建议进行以下更改......

   $query1 = "INSERT INTO [RC.table1] (terminname, datum) VALUES (?, ?);select @@identy"

现在,检索结果(将添加新密钥)并将其作为参数传递给下一个SQL调用。