This concerns me a little:
"...the need to support some operations that require postId to be inserted as is (no re-numbering)..."
I assume this sort of operation is the exception, and not the norm? I can also only assume that you're inserting the same post with the same Post ID into the same table without deleting the original? It's still not clear WHY you want to do this.
I really don't see why you'd need to worry about changing the Post ID if you're assigning posts to another user. Nothing else changes except the values in the User ID column by the sounds of it. Unless you mean you can have two or more posts with the same Post ID and the same User ID. If so, why?
To answer your questions:
- No, IDENTITY_INSERT cannot be set globally. It is a per object, per session setting.
- Using MAX(PostID) + 1 doesn't make sense. Is there a reason why IDENTITY(1, 1) doesn't work for the PostID column? You can re-seed if necessary.
- Don't use application-generated UUIDs as key values. They make queries so much slower. At worst, use NEWSEQUENTIALID() in SQL Server if you absolutely want to use a UUID. UUIDs unnecessarily bloat tables and indexes, and with the exception of NEWSEQUENTIALID, are query performance killers.
- What you could do is have a Primary key column simply called ID, and then a surrogate key called Post ID if that needs to be non-unique. That way, when you copy a post, the copy of the original gets a new ID, but still retains the original Post ID, but with no need to worry about doing anything unnecessary to the PK.
However, without any changes to the application or the DB, what I would suggest is using a stored procedure executed as the owner of the stored proc (which also owns the Posts table) to set IDENTITY_INSERT to ON only when absolutely necessary. Here is an example I've just written:
create procedure dbo.sp_CopyPost
(
@PostID INT
,@UserID INT
)
with execute as owner
as
begin
set nocount on;
set identity_insert dbo.Posts on;
begin tran
insert into dbo.Posts
(
PostID
,UserID
--Whatever other columns
)
values
(
@PostID
,@UserID
--Whatever other values
)
commit tran
set identity_insert dbo.Posts off;
select @@IDENTITY
end
That will do what you want, based on the current wording of your question, and the comments you've made.
If you need to essentially "plug the gaps" in your identity column, you will find Microsoft-recommended queries to do so in section B here:
https://msdn.microsoft.com/en-us/library/ms186775.aspx