The last_insert_id() call is simply a wrapper around a "select @@identity" query. To be successful (i.e. to return the correct value) this must be executed on the same connection as the INSERT that generated the new IDENTITY value. Therefore the statement handle that was used to perform the insert must have been closed/freed before last_insert_id() can be called. Otherwise last_insert_id() will be forced to open a different connection to perform the query, and will return an invalid value (usually in this case it will return 0).