June 7, 2012

sp_replmonitorhelpmergesession (Transact-SQL MetaData) Definition

Please note: that the following source code is provided and copyrighted by Microsoft and is for educational purpose only.
The meta data is from an SQL 2012 Server.

I have posted alot more, find the whole list here.

Goto Definition or MetaData

Definition:

sys.sp_replmonitorhelpmergesession(nvarchar @agent_name
, int @hours
, int @session_type
, nvarchar @publisher
, nvarchar @publisher_db
, nvarchar @publication)

MetaData:

 create procedure sys.sp_replmonitorhelpmergesession  
(
@agent_name nvarchar(100)= NULL,
@hours int = 0, -- @hours < 0 will return TOP 100, otherwise look back at only @hours --
@session_type int = 1, -- 1 for succeed/retry sessions, otherwise failure sessions --
@publisher sysname = NULL, -- used to read subscriber-side monitoring tables.
@publisher_db sysname = NULL, -- used to read subscriber-side monitoring tables.
@publication sysname = NULL -- used to read subscriber-side monitoring tables.
)
as
begin
set nocount on

declare @min_time datetime
declare @retcode int
declare @succeed int
declare @running int
declare @retry int
declare @failure int
declare @isdistdb bit
declare @agent_id int
declare @max_session_id int
declare @max_running_session_id int

select @succeed = 2
select @retry = 5
select @failure = 6
select @running = 3

--
-- security check : replmonitor
--
if not (is_member(N'db_owner') = 1 or isnull(is_member(N'replmonitor'),0) = 1)
begin
raiserror(14260, 16, -1)
return (1)
end

select @isdistdb = sys.fn_MSrepl_isdistdb(DB_NAME())

if @isdistdb = 1 and @agent_name is null
begin
raiserror(14043, 16, -1, '@agent_name', 'sp_replmonitorhelpmergesession')
return 1
end
else if @isdistdb = 0 and (@publisher is null or @publisher_db is null or @publication is null)
begin
-- subscriber-side monitoring
if @publisher is null
raiserror(14043, 16, -1, '@publisher', 'sp_replmonitorhelpmergesession')
if @publisher_db is null
raiserror(14043, 16, -1, '@publisher_db', 'sp_replmonitorhelpmergesession')
if @publication is null
raiserror(14043, 16, -1, '@publication', 'sp_replmonitorhelpmergesession')
return 1
end

if @isdistdb = 1
begin

select @agent_id = id from dbo.MSmerge_agents where name = @agent_name

select top 1 @max_session_id = session_id from dbo.MSmerge_sessions with (NOLOCK)
where agent_id = @agent_id
order by session_id desc

select @max_running_session_id = @max_session_id

select top 1 @max_running_session_id = session_id from dbo.MSmerge_sessions with (NOLOCK)
where agent_id = @agent_id and runstatus = @running
order by session_id desc

IF @hours < 0
BEGIN
select top 100
sessions.session_id as Session_id,
case when sessions.runstatus = 3 and sessions.session_id <> @max_running_session_id and sys.fn_replmerge_get_errormsgcounts(sessions.session_id) <> 0 then @failure
when sessions.runstatus = 3 and sessions.session_id <> @max_running_session_id and sys.fn_replmerge_get_errormsgcounts(sessions.session_id) = 0 then @succeed
when sessions.runstatus is null then 0 else sessions.runstatus end as Status,
sessions.start_time as StartTime,
sessions.end_time as EndTime,
sessions.duration as Duration,
sys.fn_replmerge_get_cmdcounts(sessions.session_id, 1) as UploadedCommands,
sys.fn_replmerge_get_cmdcounts(sessions.session_id, 2) as DownloadedCommands,
sys.fn_replmerge_get_errormsgcounts(sessions.session_id) as ErrorMessages,
(
select top 1 re.id from dbo.MSrepl_errors re
where re.session_id = sessions.session_id
order by re.id desc
) as ErrorID,
sessions.percent_complete as PercentageDone,
sessions.time_remaining as TimeRemaining,
sessions.current_phase_id as CurrentPhase,
(
select top 1 rh.comments from dbo.MSmerge_history rh
where rh.session_id = sessions.session_id
order by rh.session_id desc, rh.timestamp desc
) as LastMessage,
-- IsSpidActive = case when exists (select * from sys.dm_exec_sessions sp where sp.login_time = sessions.spid_login_time
-- and sp.session_id = sessions.spid) then 1 else 0 end
IsSpidActive = 1
from dbo.MSmerge_sessions sessions
where sessions.agent_id = @agent_id
and sessions.session_id <= @max_session_id
and
(
(
@session_type = 1 and
(
sessions.runstatus = @succeed
or sessions.runstatus = @retry
or sessions.runstatus = @running
or sessions.session_id = @max_session_id
)
)
or sessions.runstatus = @failure
)
order by sessions.start_time desc
END
ELSE
BEGIN
IF @hours = 0
BEGIN
select @min_time = NULL
END
ELSE
BEGIN
select @min_time = dateadd(hour, -@hours, getdate())
END
-- phase is ReconcilerMsg.lPhase: UPLOAD_PHASE as 2 and DOWNLOAD_PHASE as 3
-- dbo.MSmerge_articlehistory.phase_id
select
sessions.session_id as Session_id,
case when sessions.runstatus = 3 and sessions.session_id <> @max_running_session_id and sys.fn_replmerge_get_errormsgcounts(sessions.session_id) <> 0 then @failure
when sessions.runstatus = 3 and sessions.session_id <> @max_running_session_id and sys.fn_replmerge_get_errormsgcounts(sessions.session_id) = 0 then @succeed
when sessions.runstatus is null then 0 else sessions.runstatus end as Status,
sessions.start_time as StartTime,
sessions.end_time as EndTime,
sessions.duration as Duration,
sys.fn_replmerge_get_cmdcounts(sessions.session_id, 1) as UploadedCommands,
sys.fn_replmerge_get_cmdcounts(sessions.session_id, 2) as DownloadedCommands,
sys.fn_replmerge_get_errormsgcounts(sessions.session_id) as ErrorMessages,
(
select top 1 re.id from dbo.MSrepl_errors re
where re.session_id = sessions.session_id
order by re.id desc
) as ErrorID,
sessions.percent_complete as PercentageDone,
sessions.time_remaining as TimeRemaining,
sessions.current_phase_id as CurrentPhase,
(
select top 1 rh.comments from dbo.MSmerge_history rh
where rh.session_id = sessions.session_id
order by rh.session_id desc, rh.timestamp desc
) as LastMessage,
-- IsSpidActive = case when exists (select * from sys.dm_exec_sessions sp where sp.login_time = sessions.spid_login_time
-- and sp.session_id = sessions.spid) then 1 else 0 end
IsSpidActive = 1
from dbo.MSmerge_sessions sessions
where sessions.agent_id = @agent_id
and sessions.session_id <= @max_session_id
and
(
(
@session_type = 1 and
(
sessions.runstatus = @succeed
or sessions.runstatus = @retry
or sessions.runstatus = @running
or sessions.session_id = @max_session_id
)
)
or sessions.runstatus = @failure
)
and (sessions.end_time >= @min_time or @min_time IS NULL)
order by sessions.start_time desc
END
end
else
begin
exec @retcode = sys.sp_MShelp_subscriberside_history
@hours=@hours, @session_type=@session_type, @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication
if @@error <> 0 or @retcode <> 0
return 1
end

return 0
end

sp_replmonitorrefreshjob (Transact-SQL MetaData) Definition

Please note: that the following source code is provided and copyrighted by Microsoft and is for educational purpose only.
The meta data is from an SQL 2012 Server.

I have posted alot more, find the whole list here.

Goto Definition or MetaData

Definition:

sys.sp_replmonitorrefreshjob(tinyint @iterations
, bit @profile)

MetaData:

 create procedure sys.sp_replmonitorrefreshjob   
(
@iterations tinyint = 0 -- 0 - run continuously, non 0 - run for specified iterations
,@profile bit = 0 -- for internal use - DO NOT DOCUMENT (remove this before release)
)
as
begin
set nocount on
declare @retcode int
,@distribution_db sysname
,@loopcounter tinyint
,@prechecksum int
,@postchecksum int
,@lastcomputetime int
,@delaytime int
,@strdelaytime sysname
,@datebuf datetime
,@refreshpolicy tinyint

--
-- initialize
--
select @distribution_db = db_name()
,@loopcounter = 0
,@prechecksum = 0
,@postchecksum = 0
,@lastcomputetime = 0
,@refreshpolicy = 1
--
-- security check
--
if not (is_member(N'db_owner') = 1 or isnull(is_member(N'replmonitor'),0) = 1)
begin
raiserror(14260, 16, -1)
return (1)
end
--
-- security: Has to be executed from distribution database
--
if sys.fn_MSrepl_isdistdb (@distribution_db) != 1
begin
raiserror (21482, 16, -1, 'sp_replmonitorrefreshjob', 'distribution')
return 1
end
--
-- validate @iterations
--
if (@iterations < 0)
begin
raiserror(20587, 16, -1, '@iterations', 'sp_replmonitorrefreshjob')
return (1)
end
--
-- We are going through the main loop to do refresh
--
while (1=1)
begin
--
-- get the checksum value before refresh
--
select @prechecksum = checksum(time_stamp)
from dbo.MSreplication_monitordata

--
-- refresh the cache
--
exec @retcode = sys.sp_replmonitorrefreshdata @refreshpolicy = @refreshpolicy, @profile = @profile
if @retcode != 0 or @@error != 0
return 1
--
-- check if we need to break out of loop
--
if (@iterations > 0)
begin
select @loopcounter = @loopcounter + 1
if (@profile = 1)
raiserror('Completed %d iteration(s)', 10, 1, @loopcounter)
if (@iterations = @loopcounter)
break
end
--
-- we need to wait for next cycle
-- get the checksum value after refresh
--
select @postchecksum = checksum(time_stamp)
,@lastcomputetime = isnull(computetime, 0)
from dbo.MSreplication_monitordata

--
-- compute how much to wait in seconds
--
select @delaytime = case
-- no changes were there in cache
when (@prechecksum = @postchecksum) then case when (30 > @lastcomputetime) then 30 else @lastcomputetime end
-- changes were there in cache
else case when (4 > @lastcomputetime) then 4 else @lastcomputetime end
end
--
-- convert the delaytime to usable format
--
select @datebuf = dateadd(ss, @delaytime, 0x0)
select @strdelaytime = cast(datepart(hh, @datebuf) as nvarchar(4)) + N':'
+ cast(datepart(mi, @datebuf) as nvarchar(4)) + N':'
+ cast(datepart(ss, @datebuf) as nvarchar(6))
--
-- wait for given delay
--
if (@profile = 1)
raiserror('Waitfor delay %s', 10, 1, @strdelaytime)
waitfor delay @strdelaytime
end -- while (1=1)
--
-- all done
--
return 0
end

sp_requestpeerresponse (Transact-SQL MetaData) Definition

Please note: that the following source code is provided and copyrighted by Microsoft and is for educational purpose only.
The meta data is from an SQL 2012 Server.

I have posted alot more, find the whole list here.

Goto Definition or MetaData

Definition:

sys.sp_requestpeerresponse(nvarchar @publication
, nvarchar @description)

MetaData:

 create procedure sys.sp_requestpeerresponse  
(
@publication sysname,
@description nvarchar(4000) = NULL,
@request_id int = NULL output
)
as
begin
set nocount on

declare @OPT_ENABLED_FOR_P2P int

declare @retcode int,
@cmd nvarchar(4000),
@originator sysname,
@originator_db sysname

select @OPT_ENABLED_FOR_P2P = 0x1

select @cmd = NULL,
@request_id = NULL,
@originator = publishingservername(),
@originator_db = db_name()

-- Security Check
exec @retcode = sys.sp_MSreplcheck_publish
if @@error <> 0 or @retcode <> 0
begin
return 1
end

-- this procedure can not be executed in a user
-- transaction because it needs to be in its own tran
-- space (it can not be mixed with replicated cmds).
--
-- we use this tmp table insert to force any implicit
-- transaction (user may set IMPLICIT_TRANSACTIONs on)
declare @check_tran table(col1 int)
insert into @check_tran(col1) values (1)

if @@trancount > 0
begin
-- The procedure 'sp_requestpeerresponse' cannot be executed within a transaction.
raiserror(15002, 16, -1, 'sp_requestpeerresponse')
return 1
end

-- check this db is published
if sys.fn_MSrepl_istranpublished(db_name(),0) <> 1
begin
-- The database is not published.
raiserror (18757, 16, -1)
return 1
end

-- check publication name
if @publication is null
begin
-- The parameter @publication cannot be NULL.
raiserror (14043, 16, -1, @publication, 'sp_requestpeerresponse')
return 1
end

-- validate publication setting
if not exists(select *
from syspublications
where (options & @OPT_ENABLED_FOR_P2P) = @OPT_ENABLED_FOR_P2P
and name = @publication)
begin
-- The Peer-To-Peer publication ''%s'' does not exist.
raiserror (20808, 16, -1, @publication)
return 1
end

-- if there are no matching peer subscriptions
-- we will just raise an error and exit out...
if not exists(select *
from MSpeer_lsns
where (originator != UPPER(@originator)
or originator_db != @originator_db)
and originator_publication = @publication)
begin
-- No Peers were found for @originator:@originator_db:@publication.
raiserror(20807, 16, -1, @originator, @originator_db, @publication)
return 1
end

begin transaction tr_sp_requestpeerresponse
save transaction tr_sp_requestpeerresponse

insert into MSpeer_request
(
publication,
description
)
values
(
@publication,
@description
)
if @@error <> 0
begin
-- The procedure sys.sp_requestpeerresponse failed to INSERT into the resource MSpeer_request. Server error = 0.
raiserror (21499, 16, -1, 'sys.sp_requestpeerresponse', 'INSERT into', 'MSpeer_request.', @@error)
goto FAILURE
end

select @request_id = scope_identity()

insert into MSpeer_response
(
request_id,
peer,
peer_db
)
select distinct @request_id,
UPPER(originator),
originator_db
from MSpeer_lsns
where (originator != UPPER(@originator)
or originator_db != @originator_db)
and originator_publication = @publication
if @@error <> 0
begin
-- The procedure sys.sp_requestpeerresponse failed to INSERT into the resource MSpeer_response. Server error = 0.
raiserror (21499, 16, -1, 'sys.sp_requestpeerresponse', 'INSERT into', 'MSpeer_response.', @@error)
goto FAILURE
end

select @cmd = N'exec sys.sp_MSpeersendresponse @request_id=' + cast(@request_id as nvarchar) +
N',@originator=N' + quotename(@originator, '''') +
N',@originator_db=N' + quotename(@originator_db, '''') +
N',@originator_publication=N' + quotename(@publication, '''')

exec @retcode = sys.sp_MSpeertopeerfwdingexec @command = @cmd,
@publication = @publication,
@execute = 0,
@change_results_originator = 1
if @@error <> 0 or @retcode <> 0
goto FAILURE

commit transaction tr_sp_requestpeerresponse

return 0
FAILURE:
rollback transaction tr_sp_requestpeerresponse
commit transaction

return 1
end

sp_replication_agent_checkup (Transact-SQL MetaData) Definition

Please note: that the following source code is provided and copyrighted by Microsoft and is for educational purpose only.
The meta data is from an SQL 2012 Server.

I have posted alot more, find the whole list here.

Goto Definition or MetaData

Definition:

sys.sp_replication_agent_checkup(int @heartbeat_interval)

MetaData:

 create procedure sys.sp_replication_agent_checkup  
@heartbeat_interval int = 10 -- minutes
as
declare @distribution_db sysname
declare @retstatus int
declare @proc nvarchar(255)
declare @retcode int

--
-- Security Check: require sysadmin
--
IF (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0)
BEGIN
RAISERROR(21089,16,-1)
RETURN (1)
END

declare hCdistdbs CURSOR LOCAL FAST_FORWARD for
select name from msdb..MSdistributiondbs where
has_dbaccess(name) = 1
for read only
open hCdistdbs
fetch hCdistdbs into @distribution_db
while @@fetch_status <> -1
begin
select @proc = QUOTENAME(@distribution_db) + '.sys.sp_MSagent_retry_stethoscope'
execute @retcode = @proc
if @@error <> 0 or @retcode <> 0
begin
select @retstatus = 1
goto UNDO
end

select @proc = QUOTENAME(@distribution_db) + '.sys.sp_MSagent_stethoscope'
execute @retcode = @proc @heartbeat_interval
if @@error <> 0 or @retcode <> 0
begin
select @retstatus = 1
goto UNDO
end
fetch hCdistdbs into @distribution_db
end

set @retstatus = 0

UNDO:
close hCdistdbs
deallocate hCdistdbs
return (@retstatus)

sp_replgetparsedddlcmd (Transact-SQL MetaData) Definition

Please note: that the following source code is provided and copyrighted by Microsoft and is for educational purpose only.
The meta data is from an SQL 2012 Server.

I have posted alot more, find the whole list here.

Goto Definition or MetaData

Definition:

sys.sp_replgetparsedddlcmd(nvarchar @FirstToken
, nvarchar @objectType
, nvarchar @dbname
, nvarchar @owner
, nvarchar @objname
, nvarchar @targetobject)

MetaData:

 --   
-- Name: sp_replgetparsedddlcmd
--
-- Description: This helper sproc strips out the first part
-- of DDL cmd, up to the point right after object name.
--
--
-- Parameters:
-- @ddlcmd nvarchar(max)
-- ,@FirstToken sysname
-- ,@objectType sysname -- comlete form: e.g. procedure/function/tigger
-- ,@dbname sysname -- not quoted
-- ,@owner sysname -- not quoted
-- ,@objname sysname -- not quoted
-- ,@targetobject nvarchar(512)-- applies to alter trigger only
--
-- Returns: nvarchar(max)
--
-- Notes: this is an internal helper function which assumes
-- incoming @ddlcmd is always valid, it strips out the first
-- part of ddl so we can reconstruct with alternate
-- destination table/owner if so desired, it also helps to
-- to avoid blandly sending DDL with fully qualified table
-- name including publisher database:
-- e.g.
-- sp_replgetparsedddlcmd
-- N'table pubs.dbo.authors add newcol1 int'
-- ,'alter'
-- ,'table'
-- ,'pubs'
-- ,'dbo'
-- ,'authors'
-- should return: N'add newcol1 int'
--
-- Security: not exposed to public
--
create procedure sys.sp_replgetparsedddlcmd
@ddlcmd nvarchar(max) OUTPUT
,@FirstToken sysname
,@objectType sysname -- comlete form: e.g. procedure/function/tigger
,@dbname sysname -- not quoted
,@owner sysname -- not quoted
,@objname sysname -- not quoted
,@targetobject nvarchar(512)-- applies to alter trigger only
as
begin
declare @left_quote bigint
,@right_quote bigint
,@first_space tinyint
,@ddlcmd_len bigint
,@ddloffset nvarchar(max)
,@trigger_dbname sysname
,@trigger_owner sysname
,@trigger_objname sysname

-- start with striping off ALTER at the begining
set @ddloffset = ltrim(right(@ddlcmd, len(@ddlcmd) - len(@FirstToken)))

-- strip out any possible comments between alter and next token
set @ddloffset = sys.fn_replremoveleadingcomments(@ddloffset)
set @ddlcmd_len = len(@ddloffset)

-- now strip out objectType token,
-- remember, this function is only used by DDL trigger where we know @ddlcmd coming in is valid
-- watch out for space after the second token, e.g. alter proc instead of alter procedure
-- watch out for comments, e.g. alter proc-- .. -- myproc instead of alter procedure
set @first_space = patindex('% %', @ddloffset)
set @left_quote = patindex('%-- %', @ddloffset)
if (@first_space > 0 and @first_space < len(@objectType))
or (@left_quote > 0 and @left_quote < len(@objectType))
begin
if (@first_space > 0) and (@left_quote > 0)
begin
if (@left_quote > @first_space)
set @left_quote = @first_space
end
else if (@first_space > 0) and (@left_quote = 0)
set @left_quote = @first_space
end
else
set @left_quote = len(@objectType) + 1
set @ddloffset = ltrim(substring(@ddloffset, @left_quote, @ddlcmd_len - @left_quote + 1))

-- strip out any possible comments between @ObjectType token and object name
set @ddloffset = sys.fn_replremoveleadingcomments(@ddloffset)

-- now strip out object name
-- deal with the following possibilities: w or w/o quotes
-- [db].[owner].[obj]
set @ddloffset = sys.fn_replremovefullobj(@ddloffset, @dbname, @owner, @objname)

-- might as well strip out any possible comments between object name and definition
set @ddloffset = sys.fn_replremoveleadingcomments(@ddloffset)

-- alter trigger trigger_name on [db].[owner].[obj] as .... has the same issue, parse to the point before as
-- so we can substitute with alter trigger trigger_name on [dest_owner].[dest_obj] as
if UPPER(@objectType) = N'TRIGGER' and @targetobject is not NULL and len(@targetobject) > 0
begin
-- remove leading white space char
declare @pos int
select @pos=charindex(N'on ', @ddloffset)
set @ddloffset = substring(@ddloffset, @pos, len(@ddloffset)-@pos+1)

set @ddloffset = ltrim(right(@ddloffset, len(@ddloffset) - len(N'on ')))

set @trigger_dbname = isnull(parsename(@targetobject, 3), @dbname)
set @trigger_owner = isnull(parsename(@targetobject, 2), @owner)
set @trigger_objname = isnull(parsename(@targetobject, 1), @objname)

set @ddloffset = sys.fn_replremovefullobj(@ddloffset, @trigger_dbname, @trigger_owner, @trigger_objname)
end
set @ddlcmd=@ddloffset
return 0
end

sp_remoteoption (Transact-SQL MetaData) Definition

Please note: that the following source code is provided and copyrighted by Microsoft and is for educational purpose only.
The meta data is from an SQL 2012 Server.

I have posted alot more, find the whole list here.

Goto Definition or MetaData

Definition:

sys.sp_remoteoption(nvarchar @remoteserver
, nvarchar @loginame
, nvarchar @remotename
, varchar @optname
, varchar @optvalue)

MetaData:

 create procedure sys.sp_remoteoption  
@remoteserver sysname, -- server name to change
@loginame sysname = NULL, -- user's local user name
@remotename sysname = NULL, -- user's remote name
@optname varchar(35) = NULL, -- option name to turn on/off
@optvalue varchar(10) = NULL -- true or false
as
raiserror(15207,0,-1)
return (0)

sp_refresh_log_shipping_monitor (Transact-SQL MetaData) Definition

Please note: that the following source code is provided and copyrighted by Microsoft and is for educational purpose only.
The meta data is from an SQL 2012 Server.

I have posted alot more, find the whole list here.

Goto Definition or MetaData

Definition:

sys.sp_refresh_log_shipping_monitor(uniqueidentifier @agent_id
, tinyint @agent_type
, nvarchar @database
, tinyint @mode)

MetaData:

 create procedure sys.sp_refresh_log_shipping_monitor   
(
@agent_id uniqueidentifier -- primary/secondary ID
,@agent_type tinyint -- 0 = Backup, 1 = Copy, 2 = Restore
,@database sysname = NULL -- primary/secondary database
,@mode tinyint -- 1 = refresh, 2 = delete
)
as
begin
set nocount on
declare @retcode int
,@agent_idstring sysname
,@monitor_server sysname
,@monitor_server_security_mode int
,@linkcmd nvarchar(4000)
,@istrustworthyset bit
--
-- security check
--
exec @retcode = sys.sp_MSlogshippingsysadmincheck
if (@retcode != 0 or @@error != 0)
return 1
--
-- validate agent_type
--
if (@agent_type not in (0,1,2))
begin
raiserror(21055, 16, -1, '@agent_type','sp_refresh_log_shipping_monitor')
return 1
end
--
-- validate mode
--
if (@mode not in (1,2))
begin
raiserror(21055, 16, -1, '@mode','sp_refresh_log_shipping_monitor')
return 1
end
--
-- must be invoked from master db
--
if (db_name() != N'master')
begin
raiserror(5001, 16,-1)
return 1
end
--
-- validate agent
--
if (sys.fn_MSvalidatelogshipagentid(@agent_id, @agent_type) = 0)
begin
select @agent_idstring = cast(@agent_id as sysname)
raiserror(32016, 16, 1, @agent_idstring, @agent_type)
return 1
end
--
-- if database is supplied - validate it
--
if (@database is not null)
begin
if (@agent_type = 0) and not exists (select *
from msdb.dbo.log_shipping_primary_databases
where primary_database = @database
and primary_id = @agent_id)
begin
raiserror(32010, 16, 2, @database)
return 1
end
else if (@agent_type in (1,2)) and not exists (select *
from msdb.dbo.log_shipping_secondary_databases as sd
join msdb.dbo.log_shipping_secondary as s
on sd.secondary_id = s.secondary_id
where sd.secondary_database = @database
and s.secondary_id = @agent_id)
begin
raiserror(32014, 16, 3, @database)
return 1
end
end
--
-- get monitor server information
--
if (@agent_type = 0)
begin
select @monitor_server = monitor_server
,@monitor_server_security_mode = monitor_server_security_mode
from msdb.dbo.log_shipping_primary_databases
where primary_id = @agent_id
end
else
begin
select @monitor_server = monitor_server
,@monitor_server_security_mode = monitor_server_security_mode
from msdb.dbo.log_shipping_secondary
where secondary_id = @agent_id
end
--
-- for local monitor - no need do anything
--
if (upper(@monitor_server) = upper(@@servername))
return 0
--
-- The monitor is not local - check for impersonation
--
select @retcode = 0
if (@monitor_server_security_mode = 0) and (suser_name() != SUSER_SNAME(0x01))
begin
--
-- execute using proxy
--
exec @retcode = sys.sp_MSproxylogshippingmonitorrefresh
@agent_id = @agent_id
,@agent_type = @agent_type
,@database = @database
,@mode = @mode
,@monitor_server = @monitor_server
end
else
begin
--
-- cleanup metadata first
--
if (@agent_type = 0)
begin
--
-- delete Primary monitor data
--
select @linkcmd = quotename(sys.fn_MSgetlogshippingmoniterlinkname(upper(@monitor_server))) + N'.msdb.sys.sp_processlogshippingmonitorprimary'
begin try
exec @retcode = @linkcmd @mode = 2
,@primary_id = @agent_id
,@primary_server = @@servername
,@monitor_server = @monitor_server
,@monitor_server_security_mode = @monitor_server_security_mode
end try
begin catch
select @retcode = 1
end catch
end
else
begin
--
-- delete Secondary monitor data
--
select @linkcmd = quotename(sys.fn_MSgetlogshippingmoniterlinkname(upper(@monitor_server))) + N'.msdb.sys.sp_processlogshippingmonitorsecondary'
begin try
exec @retcode = @linkcmd @mode = 2
,@secondary_server = @@servername
,@secondary_database = @database
,@secondary_id = @agent_id
,@monitor_server = @monitor_server
,@monitor_server_security_mode = @monitor_server_security_mode
end try
begin catch
select @retcode = 1
end catch
end
if (@retcode != 0 or @@error != 0)
goto cleanup
--
-- If we deleting - then we are done
--
if (@mode = 2)
goto cleanup
--
-- refresh now
--
if (@agent_type = 0)
begin
--
-- refresh primary data
--
select @linkcmd = N'insert into ' + quotename(sys.fn_MSgetlogshippingmoniterlinkname(upper(@monitor_server))) + N'.msdb.dbo.log_shipping_monitor_primary '
+ N'(primary_id,primary_server,primary_database,backup_threshold,threshold_alert,threshold_alert_enabled,last_backup_file,last_backup_date,last_backup_date_utc,history_retention_period) '
+ N'select primary_id,primary_server,primary_database,backup_threshold,threshold_alert,threshold_alert_enabled,last_backup_file,last_backup_date,last_backup_date_utc,history_retention_period '
+ N'from msdb.dbo.log_shipping_monitor_primary where primary_id = N''' + CAST(@agent_id as nvarchar(50)) + ''' '
begin try
EXEC(@linkcmd)
end try
begin catch
select @retcode = 1
end catch
end
else
begin
--
-- refresh secondary data
--
select @linkcmd = N'insert into ' + quotename(sys.fn_MSgetlogshippingmoniterlinkname(upper(@monitor_server))) + N'.msdb.dbo.log_shipping_monitor_secondary '
+ N'(secondary_server,secondary_database,secondary_id,primary_server,primary_database,restore_threshold,threshold_alert,threshold_alert_enabled'
+ N',last_copied_file,last_copied_date, last_copied_date_utc, last_restored_file,last_restored_date, last_restored_date_utc, last_restored_latency, history_retention_period) '
+ N'select secondary_server,secondary_database,secondary_id,primary_server,primary_database,restore_threshold,threshold_alert,threshold_alert_enabled'
+ N',last_copied_file,last_copied_date, last_copied_date_utc, last_restored_file,last_restored_date, last_restored_date_utc, last_restored_latency, history_retention_period '
+ N'from msdb.dbo.log_shipping_monitor_secondary where secondary_server = @@servername and '
+ N'secondary_id = N''' + CAST(@agent_id as nvarchar(50)) + ''' '
IF (@database is not null)
BEGIN
SELECT @linkcmd = @linkcmd + N'and secondary_database = ''' + sys.fn_replreplacesinglequote(CAST(@database as nvarchar(128))) + ''' '
END
begin try
EXEC(@linkcmd)
end try
begin catch
select @retcode = 1
end catch
end
if @@error != 0 OR @retcode != 0
goto cleanup
--
-- refresh history
--
select @linkcmd = N'insert into ' + quotename(sys.fn_MSgetlogshippingmoniterlinkname(upper(@monitor_server))) + N'.msdb.dbo.log_shipping_monitor_history_detail '
+ N'(agent_id,agent_type,session_id,database_name,session_status,log_time,log_time_utc,message) '
+ N'select agent_id,agent_type,session_id,database_name,session_status,log_time,log_time_utc,message '
+ N'from msdb.dbo.log_shipping_monitor_history_detail where agent_id = N''' + CAST(@agent_id as nvarchar(50)) + ''' '
begin try
EXEC(@linkcmd)
end try
begin catch
select @retcode = 1
end catch
if @@error != 0 OR @retcode != 0
goto cleanup
--
-- refresh error
--
select @linkcmd = N'insert into ' + quotename(sys.fn_MSgetlogshippingmoniterlinkname(upper(@monitor_server))) + N'.msdb.dbo.log_shipping_monitor_error_detail '
+ N'(agent_id,agent_type,session_id,database_name,sequence_number,log_time,log_time_utc,message,source,help_url) '
+ N'select agent_id,agent_type,session_id,database_name,sequence_number,log_time,log_time_utc,message,source,help_url '
+ N'from msdb.dbo.log_shipping_monitor_error_detail where agent_id = N''' + CAST(@agent_id as nvarchar(50)) + ''' '
begin try
EXEC(@linkcmd)
end try
begin catch
select @retcode = 1
end catch
end -- no proxy execution

cleanup:

--
-- all done
--
if (@retcode = 0)
return 0
else
begin
raiserror(32055, 16, 2)
return 1
end
end

sp_repladdcolumn (Transact-SQL MetaData) Definition

Please note: that the following source code is provided and copyrighted by Microsoft and is for educational purpose only.
The meta data is from an SQL 2012 Server.

I have posted alot more, find the whole list here.

Goto Definition or MetaData

Definition:

sys.sp_repladdcolumn(nvarchar @source_object
, nvarchar @column
, nvarchar @typetext
, nvarchar @publication_to_add
, int @from_agent
, nvarchar @schema_change_script
, bit @force_invalidate_snapshot
, bit @force_reinit_subscription)

MetaData:

 create procedure sys.sp_repladdcolumn(  
@source_object nvarchar (358),
@column sysname,
@typetext nvarchar(3000),
@publication_to_add nvarchar(4000) = 'all',
@from_agent int = 0,
@schema_change_script nvarchar(4000) = NULL,
@force_invalidate_snapshot bit = 1, -- Force invalidate existing snapshot --
@force_reinit_subscription bit = 0 -- Force reinit subscription --
)
as
set nocount on
declare @objid int
declare @pubid uniqueidentifier
declare @retcode int
declare @partitioned int
declare @at_publisher bit
declare @pubname sysname
declare @artname sysname
declare @colid int
declare @tablename sysname
declare @artid uniqueidentifier
declare @tran_artid int
declare @tran_pubid int
declare @schematext nvarchar(4000)
declare @schemaversion int
declare @schematype int
declare @schemaguid uniqueidentifier
declare @conflict_table sysname
declare @ins_conflict_proc nvarchar(258)
declare @publisher sysname
declare @qual_column nvarchar(258)
declare @publisher_db sysname
declare @command nvarchar(max)
declare @sync_objid int
declare @con_id int
declare @owner sysname
declare @dest_owner sysname
declare @dest_object nvarchar(517)
declare @merge_pub_object_bit int
declare @is_for_merge bit -- 1 if merge is on AND the table is published in a merge publication AND the publication is in @publivation_to_add list
declare @is_for_tran bit
declare @not_for_merge int -- 0 if merge is on AND the table is published in a merge publication
declare @not_for_tran int
declare @dbname sysname
declare @servername sysname
declare @no_publication bit
declare @no_schema_replication bit
declare @qual_source_object nvarchar(517)
declare @len int
declare @prec int
declare @scale int
declare @typename nvarchar(270)
declare @qual_dest_object nvarchar(517)
declare @invalid_datatype bit
declare @is_yukon_datatype bit
declare @xtype int
declare @max_length int
declare @iscomputed bit
declare @pass_to_heterogenious bit
declare @merge_pub_markcolumn_bit int
declare @schema_start_lsn binary(10)
declare @schema_end_lsn binary(10)
declare @nickname int
declare @columns_in_partition int
declare @artnick int
declare @allow_initialize_from_backup bit
declare @is_timestamp_column bit
declare @is_identity_column bit
declare @is_identity_column_not_for_replication bit
,@BinVar varbinary(128)
declare @count int
declare @DATATYPE_ID_UDT int
declare @got_merge_admin_applock bit

select @got_merge_admin_applock = 0

--
-- Security Check
--
EXEC @retcode = sys.sp_MSreplcheck_publish
IF @@ERROR <> 0 or @retcode <> 0
return (1)


select @qual_column=QUOTENAME(@column)
select @merge_pub_markcolumn_bit = 0x4000

select @objid = object_id(@source_object)

-- check to see if this stored procedure is called via replication agent.
if sessionproperty('replication_agent')<>1
select @from_agent = 0
else
begin -- if table does not exists and the SP is called from replication agent, ignore the error and exit with success.
select @from_agent = 1
if @objid is NULL
return (0)
end

if @objid is NULL
begin
raiserror(14027, 16, -1, @source_object)
return (1)
end

if exists (select * from sys.columns where object_id=@objid and name=@column)
begin
if @from_agent=0
begin
raiserror(21255, 16, -1, @column, @source_object)
return (1)
end
else
return (0)
end


-- PARSENAME VARS
declare @UnqualName sysname -- rightmost name node
declare @QualName1 sysname
-- END PARSENAME VARS

select @UnqualName = PARSENAME(@source_object, 1)
select @QualName1 = PARSENAME(@source_object, 2)
if @UnqualName IS NULL
return 1
if @QualName1 is not NULL
select @owner = @QualName1
else select @owner=schema_name(schema_id) from sys.objects where object_id = @objid
select @tablename = @UnqualName

select @qual_source_object = QUOTENAME(@owner) + '.' + QUOTENAME(@tablename)
select @no_schema_replication = 0
select @no_publication=0
select @servername=publishingservername()
select @dbname=db_name()
select @merge_pub_object_bit = 128
select @not_for_merge = 0
select @not_for_tran = 0

if exists (select * from sys.objects where name='sysmergearticles')
begin
-- the article can not be inside a republisher
if @from_agent=0 and exists (select * from dbo.sysmergearticles where objid=@objid and pubid not in
(select pubid from dbo.sysmergepublications where LOWER(publisher)=LOWER(@servername) and publisher_db=@dbname))
begin
raiserror(21260, 16, -1, @dbname, @servername, @source_object)
return (1)
end
end

select @invalid_datatype=0
select @is_yukon_datatype=0
select @DATATYPE_ID_UDT = 240 -- system_type_id for UDT.
-- signal to db ddl trigger to bail out
EXEC @retcode = sys.sp_MSsetcontext_bypasswholeddleventbit @onoff=1
IF @@ERROR <> 0 or @retcode <> 0
RETURN(1)

-- the transaction below is just an experiment to validate type text --
BEGIN TRAN
SAVE TRANSACTION fake_move
exec @retcode = sys.sp_MSunmarkreplinfo @object=@tablename, @owner=@owner
if @retcode<>0 or @@ERROR<>0
begin
goto CHECKING_DONE
end
declare @temp_id int
declare @temp_colid int
select @is_identity_column = 0
select @is_timestamp_column = 0
select @is_identity_column_not_for_replication = 0
exec ('alter table ' + @qual_source_object + ' add ' + @qual_column + ' ' + @typetext)
select @temp_id = object_id(@qual_source_object)
if @temp_id is NULL
begin
raiserror(21285, 16, -1, @column, @source_object)
select @invalid_datatype = 1
GOTO CHECKING_DONE
end
select @pass_to_heterogenious=0, @temp_colid = column_id, @xtype=system_type_id, @iscomputed=is_computed,
@max_length = max_length
from sys.columns where object_id = @temp_id and name=@column
if @iscomputed <> 1 and type_name(@xtype) <> 'timestamp'
select @pass_to_heterogenious=1
if COLUMNPROPERTY(@temp_id, @column, 'IsIdentity') = 1
select @is_identity_column = 1
if type_name(@xtype) = 'timestamp'
select @is_timestamp_column = 1
if @is_identity_column = 1 and COLUMNPROPERTY(@temp_id, @column, 'IsIdNotForRepl') = 1
select @is_identity_column_not_for_replication = 1
if COLUMNPROPERTY(@temp_id, @column, 'IsIdentity') = 0
and not exists (select * from sys.columns where object_id = @temp_id and name=@column and is_nullable=1)
and not exists (select * from sysconstraints where id=@temp_id and colid=@temp_colid and OBJECTPROPERTY ( constid , 'IsDefaultCnst' ) = 1)
and @iscomputed <> 1 and type_name(@xtype) <> 'timestamp' -- not computed column nor timestamp column
begin
select @invalid_datatype = 1
end
-- Check for yukon data type.
if (@xtype = @DATATYPE_ID_UDT) OR ((@max_length = -1) and type_name(@xtype) in ('xml','varchar','nvarchar','varbinary'))
begin
select @is_yukon_datatype = 1
end
CHECKING_DONE:
ROLLBACK TRANSACTION fake_move
COMMIT TRAN
if @invalid_datatype = 1
begin
raiserror(21285, 16, -1, @column, @source_object)
return (1)
end

select @is_for_merge = 0
select @is_for_tran = 0
if not exists (select * from sys.objects where name='sysmergepublications') and
not exists (select * from sys.objects where name='syspublications')
begin
raiserror(21230, 16, -1)
return (1)
end

create table #tmp_table (name sysname collate database_default)

if LOWER(@publication_to_add)='all' or LOWER(@publication_to_add)='[all]'
begin
select @publication_to_add = '%'
end
else
begin
if charindex(',', @publication_to_add)<>0 -- publication list
begin
declare @tmp_publist nvarchar(4000)
declare @total int
declare @invalid_pub sysname
select @invalid_pub = NULL
select @tmp_publist = @publication_to_add
while @tmp_publist <> ''
begin
select @tmp_publist = LTRIM(@tmp_publist)
select @total=len(@tmp_publist)
select @len=charindex(',', @tmp_publist)
if @len=0
begin
insert #tmp_table values(@tmp_publist)
select @tmp_publist=''
end
else
begin
insert #tmp_table values(substring(@tmp_publist, 1, @len-1))
select @tmp_publist = right(@tmp_publist, @total-@len)
end
end
if exists (select * from sys.objects where name='sysmergepublications') and
exists (select * from sys.objects where name='syspublications')
select @invalid_pub=name from #tmp_table where name not in (select ('[' + name + ']') from dbo.sysmergepublications) and
name not in (select ('[' + name + ']') from syspublications)
else
if exists (select * from sys.objects where name='sysmergepublications')
select @invalid_pub=name from #tmp_table where name not in (select ('[' + name + ']') from dbo.sysmergepublications)
else
if exists (select * from sys.objects where name='syspublications')
select @invalid_pub=name from #tmp_table where name not in (select ('[' + name + ']') from syspublications)
if @invalid_pub is not NULL and @from_agent=0
begin
raiserror(21274, 16, -1, @invalid_pub)
return (1)
end
end
else
begin -- single publication
insert #tmp_table values(@publication_to_add)
insert #tmp_table values('[' + @publication_to_add + ']')
end

end

-- if in both merge and tran publication
if exists (select * from sys.objects where name='sysmergepublications')
and exists (select * from sys.objects where name='syspublications')
begin
if not exists (select * from syspublications where name like @publication_to_add
or (('[' + name + ']') in (select name from #tmp_table)))
and not exists (select * from dbo.sysmergepublications where name like @publication_to_add
or (('[' + name + ']') in (select name from #tmp_table)))
select @no_publication = 1

if not exists (select * from sysarticles where objid=@objid and pubid in
(select pubid from syspublications where repl_freq = 0 and (name like @publication_to_add
or (('[' + name + ']') in (select name from #tmp_table)))))
and not exists (select * from dbo.sysmergearticles where objid=@objid and pubid in
(select pubid from dbo.sysmergepublications where name like @publication_to_add
or (('[' + name + ']') in (select name from #tmp_table))))
select @no_schema_replication=1
end
-- if a merge publication
else if exists (select * from sys.objects where name='sysmergepublications')
begin
if not exists (select * from dbo.sysmergepublications where name like @publication_to_add
or (('[' + name + ']') in (select name from #tmp_table)))
select @no_publication = 1

if not exists (select * from dbo.sysmergearticles where objid=@objid and pubid in
(select pubid from dbo.sysmergepublications where name like @publication_to_add
or (('[' + name + ']') in (select name from #tmp_table))))
select @no_schema_replication = 1
end
-- if tran publication
else if exists (select * from sys.objects where name='syspublications')
begin
if not exists (select * from syspublications where name like @publication_to_add
or (('[' + name + ']') in (select name from #tmp_table)))
select @no_publication = 1

if not exists (select * from sysarticles where objid=@objid and pubid in
(select pubid from syspublications where repl_freq = 0 and (name like @publication_to_add
or (('[' + name + ']') in (select name from #tmp_table)))))
select @no_schema_replication =1
end

if @no_publication=1 and @publication_to_add <> '%' and LOWER(@publication_to_add)<>'none' and LOWER(@publication_to_add)<>'[none]'
begin
raiserror(21200, 16, -1, @publication_to_add)
return (1)
end

if @no_schema_replication=1 and LOWER(@publication_to_add)<>'none' and LOWER(@publication_to_add)<>'[none]'
begin
if @publication_to_add = '%'
begin
raiserror(21246, 16, -1, @source_object)
return (1)
end
else
begin
raiserror(21245, 16, -1, @source_object, @publication_to_add)
return (1)
end
end

select @at_publisher = 0

if exists (select * from sys.objects where name = 'sysarticles')
begin
if exists (select a.objid from sysarticles a, syspublications p where a.objid=@objid
and p.pubid = a.pubid
and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0))
begin
select @is_for_tran = 1
end
end

if exists (select * from sys.objects where name = 'sysmergearticles')
begin
if exists (select a.objid from sysmergearticles a, sysmergepublications p where a.objid=@objid
and p.pubid = a.pubid
and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0))
begin
select @is_for_merge = 1
end
end
else
select @is_for_merge = 0

-- Cannot add yukon specific datatypes using repladdcolumn when backward comp level is less than 90
-- for merge. For tran we never adding these datatypes using sp_repladdcolumn. Use alter table for tran.
if (@is_for_merge = 1) and (@is_yukon_datatype = 1)
begin
if ((select min(backward_comp_level) from dbo.sysmergepublications where pubid
in (select pubid from dbo.sysmergearticles where objid=@objid)) < 90)
begin
raiserror(25014, 16, -1)
return (1)
end
end
else if (@is_for_tran = 1) and (@is_yukon_datatype = 1)
begin
raiserror(25014, 16, -1)
return (1)
end

if (@is_for_tran =1 and @force_reinit_subscription = 0)
begin
if (@is_timestamp_column = 1 )
begin
raiserror(21380, 16, -1)
return (1)
end
if (@is_identity_column = 1 and @is_identity_column_not_for_replication <> 1)
begin
begin
raiserror(21810, 16, -1)
return (1)
end
end
if exists (SELECT P.pubid FROM dbo.syspublications P, dbo.sysarticles A, dbo.syssubscriptions S
WHERE A.objid = @objid and A.pubid = P.pubid and A.artid = S.artid
and (P.allow_sync_tran = 1 or P.allow_queued_tran = 1)
and S.status = 2 -- active
and S.sync_type != 2 -- not 'none'
and S.update_mode != 0 ) -- not 'read only'

begin
raiserror(21381, 16, -1, @tablename)
return (1)
end
end

begin TRAN
save tran sp_repladdcolumn
--
if not exists (select * from tempdb.sys.objects where name = '##MS_internal_old_style_DDL_support_being_used')
create table ##MS_internal_old_style_DDL_support_being_used(db_name sysname, objid int)

insert ##MS_internal_old_style_DDL_support_being_used(db_name, objid) values(db_name(), @objid)
if @@ERROR<>0
goto FAILURE
--
if not exists (select * from sys.objects where name='sysmergearticles')
select @not_for_merge = 1
else
if not exists (select * from dbo.sysmergearticles where objid=@objid)
select @not_for_merge =1

if not exists (select * from sys.objects where name='sysarticles')
select @not_for_tran = 1
else
if not exists (select * from dbo.sysarticles where objid=@objid)
select @not_for_tran =1

-- Merge only supports a max of 246 columns. Check and error out if we already have
-- 246 columns that are replicating and we are trying to add another one.

if @is_for_merge = 1
begin
select @count = count(*) from sys.columns
where object_id=@objid and
is_computed<>1 and
system_type_id <> type_id('timestamp') and
is_merge_published = 1

IF @count > 245
BEGIN
RAISERROR(25006, 16, -1, @qual_source_object, 245)
goto FAILURE
END
end


-- -- -- -- -- -- *tran alter table part
if @is_for_tran = 1
begin
if not exists (select * from sys.columns where name=@column and object_id =@objid)
begin
exec @retcode = sys.sp_MSprep_exclusive @qual_source_object
if @@ERROR<>0 or @retcode <> 0
goto FAILURE
exec @retcode = sp_replincrementlsn @schema_start_lsn OUTPUT
if @@ERROR<>0 or @retcode <> 0
goto FAILURE

exec ('alter table '+ @qual_source_object + ' add ' + @qual_column + ' ' + @typetext )
if @@ERROR<>0
goto FAILURE
end
end
-- if tran is enabled, but merge is not, sp_repladdcolumn with none pub list should just add the column
else if @not_for_merge = 1 and @not_for_tran = 0 and (LOWER(@publication_to_add) = 'none' or LOWER(@publication_to_add) = '[none]')
begin
exec ('alter table '+ @qual_source_object + ' add ' + @qual_column + ' ' + @typetext )
if @@ERROR<>0
goto FAILURE
end

-- -- -- -- -- -- *merge alter table part
if @is_for_merge=1
begin
-- obtain the snapshot/DDL/admin proc applock to avoid having contention with snapshot
-- Attempt to get the lock with no wait
exec @retcode = sys.sp_MSgetmergeadminapplock @timeout = 0, -- no wait
@lockowner = N'Transaction'
if @retcode<>0 or @@error<>0
goto FAILURE
select @got_merge_admin_applock = 1

exec @retcode = sys.sp_MSunmarkreplinfo @object=@tablename, @owner=@owner
if @retcode<>0 or @@ERROR<>0
goto FAILURE
if not exists (select * from sys.columns where name=@column and object_id =@objid)
begin
exec ('alter table '+ @qual_source_object + ' add ' + @qual_column + ' ' + @typetext )
if @@ERROR<>0
goto FAILURE
end
end
-- cannot add @not_for_tran = 1 as the case for "if none publist and both merge/tran are on"
else if @not_for_merge = 0 and (LOWER(@publication_to_add) = 'none' or LOWER(@publication_to_add) = '[none]')
begin
if not exists (select * from sys.columns where name=@column and object_id =@objid)
begin
exec ('alter table '+ @qual_source_object + ' add ' + @qual_column + ' ' + @typetext )
if @@ERROR<>0
goto FAILURE
end
end

-- Now for real work if publist is not empty
if @is_for_merge=1
begin
if not exists (select * from sys.columns where name=@column and object_id =@objid)
begin
exec ('alter table '+ @qual_source_object + ' add ' + @qual_column + ' ' + @typetext )
if @@ERROR<>0
goto FAILURE
end

--
-- whether the column is added to this publication, the articles whose underlying table contains
-- a new column will be regareded as vertically partitioned.
--
update dbo.sysmergearticles set vertical_partition=1 where objid=@objid
if @@ERROR<>0
goto FAILURE

--
-- Heterogenious subscriber are not to receive computed column or timestamp columns
--
declare #nosnapshot CURSOR LOCAL FAST_FORWARD for
select p.name, a.name, a.pubid from dbo.sysmergepublications p, dbo.sysmergearticles a
where p.pubid=a.pubid and a.objid=@objid and p.snapshot_ready=0 and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0)
and (p.sync_mode=0 or @pass_to_heterogenious=1)
open #nosnapshot
fetch #nosnapshot into @pubname, @artname, @pubid
while (@@fetch_status<>-1)
begin
-- Indicate that this is an internal caller of sp_mergearticlecolumn
EXEC @retcode = sys.sp_MSsetcontext_internalcaller @onoff=1
IF @@ERROR <> 0 or @retcode <> 0
goto ERROR_EXIT

exec @retcode = sys.sp_mergearticlecolumn @pubname, @artname, @column, 'add', 'true'
if @retcode <>0 or @@ERROR<>0
goto ERROR_EXIT

-- Turn off indication that this is an internal caller of sp_mergearticlecolumn
EXEC @retcode = sys.sp_MSsetcontext_internalcaller @onoff=0
IF @@ERROR <> 0 or @retcode <> 0
goto ERROR_EXIT

fetch #nosnapshot into @pubname, @artname, @pubid
end
CLOSE #nosnapshot
DEALLOCATE #nosnapshot


--
-- Handle those cases where snapshot is already ran and new schema change needs to be added
-- ; Heterogenious subscriber are not to receive computed column or timestamp columns
--
declare #addcolumn CURSOR LOCAL FAST_FORWARD for
select pubid, name, sync_objid, artid, nickname, conflict_table, ins_conflict_proc, destination_owner
from dbo.sysmergearticles where objid=@objid and pubid
in (select pubid from dbo.sysmergepublications where snapshot_ready>0
and (sync_mode=0 or @pass_to_heterogenious=1))
open #addcolumn
fetch #addcolumn into @pubid, @artname, @sync_objid, @artid, @artnick, @conflict_table, @ins_conflict_proc, @dest_owner
while (@@fetch_status <> -1)
BEGIN
if @dest_owner is not NULL
select @dest_object = QUOTENAME(@dest_owner) + '.' + QUOTENAME(@tablename)
else
select @dest_object = QUOTENAME(@tablename)

select @pubname=name, @publisher=publisher, @publisher_db=publisher_db
from dbo.sysmergepublications where pubid=@pubid

if @conflict_table is not NULL
begin
select @con_id = object_id(quotename(@conflict_table))
if @con_id is NULL
begin
raiserror(21286, 16, -1, @conflict_table)
GOTO INNER_FAIL
end
if not exists (select name from sys.columns where name=@column and object_id=@con_id) and (@pubname like @publication_to_add or charindex('[' + @pubname + ']', @publication_to_add)>0)
begin
select @typename = type_name(system_type_id), @len = max_length, @prec = precision,
@scale = scale, @iscomputed=is_computed, @xtype=system_type_id
from sys.columns where name=@column and object_id=@objid
-- we want to column property of 'computed' or 'timestamp' of the newly added column
if @iscomputed <> 1 and type_name(@xtype) <> 'timestamp'
begin
if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes
select @len = @len/2

exec @retcode = sys.sp_MSRecontructType @typename out, @len, @prec, @scale
if @@error<>0 OR @retcode <>0
GOTO INNER_FAIL

-- doing so instead of using @typetext as we once did is that we do not want any constraint or identity properties
-- defined on conflict tables. Also it is safe to make the column NULLable in conflict tables.
select @command = 'alter table ' + QUOTENAME(@conflict_table) + ' add ' + @qual_column + ' ' + @typename + ' NULL '
end
else
-- continue to use typetext when adding computed/timestamp column to the conflict tables.
begin
select @command = 'alter table ' + QUOTENAME(@conflict_table) + ' add ' + @qual_column + ' ' + @typetext
end
exec (@command)
if @@ERROR<>0
goto INNER_FAIL

end
end

--
-- Force the re-generation of conflict insert table cause the schema is changed for sure
--
if @ins_conflict_proc is not NULL and object_id(@ins_conflict_proc) is not NULL and (@pubname like @publication_to_add or charindex('[' + @pubname + ']', @publication_to_add)>0)
begin
select @ins_conflict_proc = QUOTENAME(@ins_conflict_proc)

exec ('drop procedure ' + @ins_conflict_proc)
if @@ERROR<>0
goto INNER_FAIL
update dbo.sysmergearticles set ins_conflict_proc=NULL where pubid=@pubid and artid=@artid
if @@ERROR<>0
goto INNER_FAIL
end

--
-- Force the regeneration of publication view for all publications that publish the current table.
--
update dbo.sysmergearticles set vertical_partition=1 where artid=@artid and pubid=@pubid
if @@ERROR<>0
goto INNER_FAIL
select @at_publisher=0
if @publisher=publishingservername() and @publisher_db=db_name()
begin
select @at_publisher=1
if @pubname like @publication_to_add or charindex('[' + @pubname + ']', @publication_to_add)>0
begin
select @schematext = 'exec sp_repladdcolumn ''' + replace(@dest_object, '''', '''''') + ''',''' + replace(@column, '''', '''''') + ''','+ QUOTENAME(@typetext) + ', ''' + replace(@publication_to_add, '''', '''''') + ''', 1'
select @schemaversion = schemaversion from dbo.sysmergeschemachange
if (@schemaversion is NULL)
set @schemaversion = 1
else
select @schemaversion = 1 + max(schemaversion) from dbo.sysmergeschemachange
set @schemaguid = newid()
set @schematype = 11 -- alter table --

-- Indicate that this is an internal caller of sp_mergearticlecolumn
EXEC @retcode = sys.sp_MSsetcontext_internalcaller @onoff=1
IF @@ERROR <> 0 or @retcode <> 0
goto INNER_FAIL

exec @retcode = sys.sp_mergearticlecolumn @pubname, @artname, @column, 'add','true'
if @retcode<>0 or @@ERROR<>0
goto INNER_FAIL -- need to deallocate cursor for this loop.

-- Turn off indication that this is an internal caller of sp_mergearticlecolumn
EXEC @retcode = sys.sp_MSsetcontext_internalcaller @onoff=0
IF @@ERROR <> 0 or @retcode <> 0
goto INNER_FAIL

exec @retcode=sys.sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
if @@ERROR<>0 or @retcode<>0
goto INNER_FAIL

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- prepare parsing event
create table #SSCE_parsedschemacmds(
id int identity,
DDLsubtype sysname,
TableOwner sysname,
TableName sysname,
ColumnName sysname NULL,
ColumnAttr sysname NULL
)
select @schematext = 'alter table ' + @dest_object + ' add ' + QUOTENAME(@column) + ' ' + @typetext
insert #SSCE_parsedschemacmds(DDLsubtype, TableOwner, TableName,
ColumnName, ColumnAttr)
exec sys.sp_replddlparser @ddlCmd=@schematext
if @@ERROR <> 0
begin
DROP TABLE #SSCE_parsedschemacmds
goto INNER_FAIL
end

-- If the sp_repladdcolumn @typetext contains foreign key constraints, use the sp_MSNonSQLDDL to post them as separate schema changes --
if exists( select * from #SSCE_parsedschemacmds psc where psc.DDLsubtype = N'ADDREFERENCE')
begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Fix up foreign key constraint names --
declare @colname sysname
declare @typeid varchar(10)
declare @modified_date datetime
declare @row_id int

DECLARE #fkcursor CURSOR LOCAL FAST_FORWARD for
select name, type, modify_date from sys.foreign_keys
where parent_object_id = @objid
order by modify_date desc

open #fkcursor
fetch #fkcursor into @colname, @typeid, @modified_date
while @@fetch_status <> -1
begin
set @row_id = NULL
select top 1 @row_id = id
from #SSCE_parsedschemacmds psc where
psc.DDLsubtype = N'ADDREFERENCE'
and len(isnull(ColumnName, '')) = 0 order by id desc

if @row_id is null
begin
break
end
else
begin
update #SSCE_parsedschemacmds set ColumnName = @colname where id = @row_id
if @@error > 0
goto INNER_FAIL
end

fetch #fkcursor into @colname, @typeid, @modified_date
end
close #fkcursor
deallocate #fkcursor


declare @statement_id int
declare @schemasubtype int
declare @subtype sysname

declare @parsed_columnname sysname
declare #alter_table_cursor CURSOR LOCAL FAST_FORWARD FOR
select DISTINCT id, DDLsubtype, ColumnName
from #SSCE_parsedschemacmds
order by id ASC
for read only
open #alter_table_cursor
fetch #alter_table_cursor into @statement_id, @subtype, @parsed_columnname

while (@@fetch_status <> -1)
begin
if @subtype=N'ADDCOLUMN'
select @schemasubtype = 1
else if @subtype = N'ADDPRIMARYKEY'
select @schemasubtype = 4
else if @subtype = N'ADDUNIQUE'
select @schemasubtype = 5
else if @subtype = N'ADDREFERENCE'
select @schemasubtype = 6
else if @subtype = N'ADDDEFAULT'
select @schemasubtype = 8
else
select @schemasubtype = 0 -- dummy row

exec @retcode = sys.sp_MSNonSQLDDL @qual_source_object, @pubid, @parsed_columnname, @schemasubtype -- add column
if @@ERROR<>0 or @retcode<>0
begin
DROP TABLE #SSCE_parsedschemacmds
close #alter_table_cursor
deallocate #alter_table_cursor
goto INNER_FAIL
end
fetch #alter_table_cursor into @statement_id, @subtype, @parsed_columnname
end -- while-loop over #alter_table_cursor
close #alter_table_cursor
deallocate #alter_table_cursor
end
else
begin
-- insert a schema change for non SQL subscribers
select @schematext = 'alter table ' + @dest_object + ' add ' + @column + ' ' + @typetext
select @schemaversion = @schemaversion + 1
set @schematype = 13 -- for non SQL subscribers use only
set @schemaguid = newid()
exec @retcode=sys.sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
if @@ERROR<>0 or @retcode<>0
begin
DROP TABLE #SSCE_parsedschemacmds
goto INNER_FAIL
end
end
DROP TABLE #SSCE_parsedschemacmds
end
end

if @at_publisher=1
begin
exec @retcode = sys.sp_MSpublicationview @publication = @pubname, @force_flag = 2, @articlename = @artname

if @retcode<>0 or @@ERROR<>0
goto INNER_FAIL
end

select @columns_in_partition=count(*) from sys.columns where object_id = @sync_objid
if @columns_in_partition>246
begin
raiserror(21759, 16, 1,@column, @source_object)
goto INNER_FAIL
end

-- only 246 colv entries are allowed if article belongs to a publication with Shiloh compat level
if ((select min(backward_comp_level) from dbo.sysmergepublications where pubid
in (select pubid from dbo.sysmergearticles where objid=@objid)) < 90)
and
sys.fn_cColvEntries_80(@pubid, @artnick) >= 246
begin
raiserror(21523,16,1,'@column','@source_object', 246)
goto INNER_FAIL
end

exec @retcode = sys.sp_MSdroparticletriggers @tablename, @owner
if @retcode<>0 or @@ERROR<>0
goto INNER_FAIL
exec @retcode = sys.sp_MSaddmergetriggers @qual_source_object
if @retcode<>0 or @@ERROR<>0
goto INNER_FAIL

--
-- Force the regeneration of merge procs for all publications that publish the current table
--
if @at_publisher=1
exec @retcode = sys.sp_MSsetartprocs @publication=@pubname, @article=@artname, @force_flag=0, @pubid=@pubid
else
exec @retcode = sys.sp_MSmakearticleprocs @pubid, @artid
if @retcode<>0 or @@ERROR<>0
goto INNER_FAIL

--
-- passing in one more parameter to sp_MSgetconflictinsertproc such that there is
-- no select statement at the end of that SP as needed else where. The default is 1.
--
exec @retcode = sys.sp_MSgetconflictinsertproc @artid, @pubid, 0, 1
if @retcode<>0 or @@ERROR<>0
goto INNER_FAIL

fetch #addcolumn into @pubid, @artname, @sync_objid, @artid, @artnick, @conflict_table, @ins_conflict_proc, @dest_owner
END
close #addcolumn
deallocate #addcolumn
end

if @is_for_tran = 1
begin
declare #trancolumn CURSOR LOCAL FAST_FORWARD for
select a.artid, p.name, p.allow_initialize_from_backup from sysarticles a, syspublications p where a.objid=@objid
and p.pubid = a.pubid
and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0)
open #trancolumn
fetch #trancolumn into @tran_artid, @pubname, @allow_initialize_from_backup
while (@@fetch_status <> -1)
BEGIN

-- Error out if the current publication allows backup subscription
-- and the column being added is a timestamp column (restriction is temporarily lifted)
-- if @allow_initialize_from_backup = 1 and @is_timestamp_column = 1
-- begin
-- raiserror(18797, 16, -1)
-- select @retcode = 1
-- goto DROPTRAN
-- end

select @artname = name, @tran_pubid = pubid, @owner = dest_owner, @tablename = dest_table from sysarticles where artid=@tran_artid
exec @retcode = sys.sp_articlecolumn @publication = @pubname, @article = @artname, @column = @column,
@operation = 'add', @change_active = 2
,@force_invalidate_snapshot = 1
,@force_reinit_subscription = 1
,@internal = 1
if @retcode <>0 or @@ERROR<>0
goto DROPTRAN
if(@force_reinit_subscription = 0)
begin
if(@owner is not NULL) and (len(@owner) > 0)
select @qual_dest_object = QUOTENAME(@owner) + N'.'
else
select @qual_dest_object = N''
if(@tablename is not null) and (len(@tablename) > 0)
select @qual_dest_object = @qual_dest_object + QUOTENAME(@tablename)
else
select @qual_dest_object = @qual_source_object
exec @retcode = sys.sp_MSrepl_schema @pubname = @pubname
,@artid = @tran_artid
,@qual_source_object = @qual_dest_object
,@column = @column
,@operation = 0 -- 0 is add, 1 is delete
,@typetext = @typetext
,@schema_change_script = @schema_change_script
if @retcode <>0 or @@ERROR<>0
goto DROPTRAN
end
exec @retcode = sys.sp_MSreinit_article
@publication = @pubname
,@article = @artname
,@need_new_snapshot = @force_invalidate_snapshot
,@need_reinit_subscription = @force_reinit_subscription
,@force_invalidate_snapshot = @force_invalidate_snapshot
,@force_reinit_subscription = @force_reinit_subscription
if @retcode <>0 or @@ERROR<>0
goto DROPTRAN
if @allow_initialize_from_backup = 1
begin
-- If the column being added is an identity column that is
-- not marked 'not for replication', do so now. Re-acquire
-- schema mod lock to make the code more resilient to changes
-- although this must have been done inside sp_Mrepl_schema
if @is_identity_column = 1 and
@is_identity_column_not_for_replication <> 1
begin
exec %%Object(MultiName = @qual_source_object).LockMatchID(ID = @objid, Exclusive = 1, BindInternal = 0)
-- exec %%Object(MultiName = @qual_source_object).LockExclusiveMatchID(ID = @objid)
if @@error <> 0 begin select @retcode = 1 goto DROPTRAN end
exec %%ColumnEx(ObjectID = @objid, Name = @column).SetIdentityNotForRepl(Value = 1)
if @@error <> 0 begin select @retcode = 1 goto DROPTRAN end
end
-- Note that the min publication autonosync lsn is
-- incremented in sp_articlecolumn
end
fetch #trancolumn into @tran_artid, @pubname, @allow_initialize_from_backup
END
close #trancolumn
deallocate #trancolumn
exec @retcode = sp_replincrementlsn @schema_end_lsn OUTPUT
if @@ERROR<>0 or @retcode <> 0
goto FAILURE
if (@schema_start_lsn is not null) and (@schema_end_lsn is not null)
begin
insert systranschemas (tabid, startlsn, endlsn, typeid) values (@objid, @schema_start_lsn, @schema_end_lsn, 51)
if @@ERROR<>0
goto FAILURE
exec @retcode = sys.sp_replflush @objid, @schema_start_lsn, @schema_end_lsn
if @@ERROR<>0 or @retcode <> 0
goto FAILURE
end
else
goto FAILURE
end

-- Get back to its original replication state --
if @is_for_merge=1
begin
exec @retcode = sys.sp_MSmarkreplinfo @tablename, @owner
if @retcode<>0 or @@ERROR<>0
goto FAILURE
end

-- end of signal
EXEC @retcode = sys.sp_MSsetcontext_bypasswholeddleventbit @onoff=0

if @got_merge_admin_applock=1
exec sys.sp_MSreleasemergeadminapplock @lockowner = N'Transaction'

COMMIT TRAN
-- delete ##MS_internal_old_style_DDL_support_being_used where db_name=db_name() and objid= @objid
return (0)

INNER_FAIL:
CLOSE #addcolumn
DEALLOCATE #addcolumn

GOTO FAILURE

ERROR_EXIT:
CLOSE #nosnapshot
DEALLOCATE #nosnapshot
GOTO FAILURE

DROPTRAN:
CLOSE #trancolumn
DEALLOCATE #trancolumn

FAILURE:
if @got_merge_admin_applock=1
exec sys.sp_MSreleasemergeadminapplock @lockowner = N'Transaction'
rollback tran sp_repladdcolumn
commit tran
raiserror(21285, 16, -1, @column, @source_object)
-- end of signal
EXEC @retcode = sys.sp_MSsetcontext_bypasswholeddleventbit @onoff=0
return (1)

Total Pageviews