The answer to the question in the title is no, it is not possible to create a hash in Solidity that you are sure will be unique, at least given the possibility of block orphaning and reorgs.
Users can pass a nonce into the transaction, but unless you trust them, you can't be sure they won't pass the same one in twice. If you're making your ID entirely based on user-supplied data, they may maliciously attempt to get IDs that other users are expecting will be assigned to different data.
If you're not worried about reorgs, you can simply increment a number inside the contract. This number will uniquely identify a single record in any given block. However, if that block is orphaned, it may end up identifying a different record in the competing block that ends up in the longest chain. This may make it inconvenient to create an application that uses it, as you may have to handle the ID created by a transaction changing after you have already displayed it or processed it.
If the record you're creating must be unique in your contract based on the data it contains, you should simply hash the data in the contract to create an ID uniquely identifying it. Hashing is quite cheap compared to storing data, so the gas costs shouldn't normally be prohibitive. This also means you know what ID the record will have before you send the transaction, which can make it easier to keep track of.
If a record with the same content needs to be createable multiple times each with a new record, you may want to use a user-created nonce, but hash that with the user's address. Have the contract verify that it doesn't already have a record with that ID, and if it does throw an error. The nonce can be tracked in the application, or it can use something that won't normally accidentally collide, like a large, client-generated random number or a client-generated timestamp. That way although a user could create transactions that would normally get the same ID, a user can't maliciously create an ID that another user expects to be assigned to their record. This also preserves your application's ability to predict in advance what ID the transaction it is sending will get, unless your user tinkers with your application to confuse it on purpose, which in most cases will only hurt themselves.