I have created a wrapper stored procedure to create publication for transactional replication for SQL Server 2008 Standard Edition SP3. But when I execute the procedure I get the following error. The column "file_exists" is not user defined. This error doesn't make any sense to me. This works on Dev environment but same code doesn't work on test environment. Dev and Test are identical as far as I can tell. I also tried to explicitly set options, made them 5496 (SELECT @@OPTIONS). Any help greatly appreciated.
-- error
Msg 50000, Level 16, State 1, Procedure CreatePublicationForDB, Line 161
Invalid column name 'file_exists'.
-- Begin Script
CREATE DATABASE TestPublication
GO
USE TestPublication
CREATE TABLE Orders(
OrderID INT PRIMARY KEY,
CustomerID INT,
ProductID INT,
UpdatedAt DATETIME,
UpdatedBy DATETIME
)
GO
CREATE TABLE Products(
ProductID INT PRIMARY KEY,
ProductName VARCHAR(100)
)
GO
CREATE VIEW V_Order
AS
SELECT o.OrderID,o.CustomerID, p.ProductName
FROM Orders o
JOIN Products p
ON o.ProductID = p.ProductID
GO
CREATE SCHEMA repl
GO
CREATE TABLE repl.ReplicationTables
(
DBName sys.sysname NOT NULL DEFAULT('TestPublication'),
SchemaOwner sys.sysname NOT NULL DEFAULT('dbo'),
TableName sys.sysname NOT NULL
)
GO
INSERT INTO repl.ReplicationTables (tablename)
VALUES('Orders'),('Products'),('V_Order')
GO
USE TestPublication
GO
CREATE PROCEDURE CreatePublicationForDB( @databaseName sysname, @publicationName sysname = @databaseName, @allow_initialize_from_backup NVARCHAR(5) = 'true')
AS
BEGIN
BEGIN TRY
SET ANSI_WARNINGS ON
SET ANSI_PADDING ON
SET ANSI_NULLS ON
SET ARITHABORT ON
SET QUOTED_IDENTIFIER ON
SET ANSI_NULL_DFLT_ON ON
SET CONCAT_NULL_YIELDS_NULL ON
DECLARE @sp_replicationdboption varchar(MAX) = ' USE '+@databaseName +';',
@sp_addpulication VARCHAR(MAX) = ' USE '+@databaseName +';',
@sp_addpublication_snapshot VARCHAR(MAX) = ' USE '+@databaseName +';',
@sp_addarticle VARCHAR(MAX) = ' USE '+@databaseName +';',
@sp_startpublication_snapshot VARCHAR(MAX) = ' USE '+@databaseName +';'
DECLARE @allow_anonymous NVARCHAR(5) = CASE WHEN @allow_initialize_from_backup = 'false' OR @allow_initialize_from_backup IS NULL THEN 'true' ELSE 'false' END
DECLARE @immediate_sync NVARCHAR(5) = @allow_anonymous, @publisher sysname = @@SERVERNAME
-- set up database publication
SET @sp_replicationdboption += '
exec sp_replicationdboption @dbname = N'''+@databaseName+ ''',
@optname = N''publish'',
@value = N''true'''
-- Publication
SET @sp_addpulication += '
exec sp_addpublication @publication = N'''+@publicationName+ ''',
@description = N''Transactional publication of database '+@databaseName+' from Publisher '+@publisher+''',
@sync_method = N''concurrent'',
@retention = 0,
@allow_push = N''true'',
@allow_pull = N''true'',
@allow_anonymous = N'''+@allow_anonymous+ ''' ,
@enabled_for_internet = N''false'',
@snapshot_in_defaultfolder = N''true'',
@compress_snapshot = N''false'',
@ftp_port = 21,
@ftp_login = N''anonymous'',
@allow_subscription_copy = N''false'',
@add_to_active_directory = N''false'',
@repl_freq = N''continuous'',
@status = N''active'',
@independent_agent = N''true'',
@immediate_sync = N'''+@immediate_sync+ ''' ,
@allow_sync_tran = N''false'',
@autogen_sync_procs = N''false'',
@allow_queued_tran = N''false'',
@allow_dts = N''false'',
@replicate_ddl = 1,
@allow_initialize_from_backup = N'''+COALESCE(@allow_initialize_from_backup, 'false')+ ''' ,
@enabled_for_p2p = N''false'',
@enabled_for_het_sub = N''false'''
IF @allow_initialize_from_backup = 'false'
BEGIN
-- publication snapshot
SET @sp_addpublication_snapshot +='
exec sp_addpublication_snapshot @publication = N'''+@publicationName+ ''',
@frequency_type = 1,
@frequency_interval = 0,
@frequency_relative_interval = 0,
@frequency_recurrence_factor = 0,
@frequency_subday = 0,
@frequency_subday_interval = 0,
@active_start_time_of_day = 0,
@active_end_time_of_day = 235959,
@active_start_date = 0,
@active_end_date = 0,
@job_login = null,
@job_password = null,
@publisher_security_mode = 1'
SET @sp_startpublication_snapshot+=' exec sys.sp_startpublication_snapshot @publication = N'''+@publicationName+ ''''
END
-- Articles
IF OBJECT_ID('tempdb..#t') IS NULL
BEGIN
PRINT 'creating temp table t'
CREATE TABLE #t (NAME sysname,objectid INT, sch_owner sysname NULL, article sysname NOT NULL, isIndexed BIT NULL, IsSchemaBound BIT NULL, TYPE CHAR(2) NULL)
END
INSERT INTO #t(NAME,objectid, sch_owner,isIndexed,IsSchemaBound, TYPE,article)
EXEC('
USE '+@databaseName + '
SELECT f.Name, f.object_id,f.sch, f.IsIndexed,f.IsSchemaBound, f.type,CASE WHEN ROW_NUMBER() OVER (PARTITION BY f.name ORDER BY f.sch) > 1 THEN f.name + CAST((ROW_NUMBER() OVER (PARTITION BY f.name ORDER BY f.sch) - 1) AS VARCHAR(2)) ELSE f.name END AS Article
FROM(
SELECT t.Name, t.object_id,t.sch, IsIndexed,IsSchemaBound, type
FROM
(SELECT DBName, SchemaOwner, TableName
FROM TestPublication.repl.ReplicationTables
GROUP BY DBName, SchemaOwner, TableName )rt JOIN
(SELECT o.Name, o.object_id,s.name AS sch, objectproperty(o.object_id, ''IsIndexed'') AS IsIndexed,objectproperty(o.object_id, ''IsSchemaBound'') AS IsSchemaBound, o.type
FROM
sys.objects o
JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE o.type IN (''U'',''V'')
AND ObjectProperty(o.object_id, ''IsMSShipped'') = 0
AND (ObjectProperty(o.object_id, ''TableHasPrimaryKey'') = 1 OR ObjectProperty(o.object_id, ''TableHasPrimaryKey'') IS NULL)
) t ON rt.tablename = t.name AND rt.SchemaOwner = t.sch
WHERE rt.DBName = '''+@databaseName + '''
) f'
)
SELECT @sp_addarticle +=
'exec sp_addarticle
@publication = N''' +@databaseName +
''', @article = N''' +t.article+
''', @source_owner = N''' +t.sch_owner +
''', @source_object = N''' + t.NAME +
''', @type = N''' +
CASE WHEN t.type = 'U' THEN 'logbased'
WHEN t.type = 'V' AND (IsIndexed = 1 OR IsSchemaBound = 1 )THEN 'indexed view schema only'
WHEN t.type = 'V' AND IsIndexed = 0 THEN 'view schema only' END
+''', @description = null,@creation_script = null,@pre_creation_cmd = N''drop'',
@schema_option = '+
CASE WHEN t.type = 'U' THEN '0x000000000803509F'
WHEN t.type = 'V' THEN '0x0000000008000001' END+
',@destination_table = N'''+t.Name+
''',@destination_owner = N'''+t.sch_owner+''''+
CASE WHEN t.TYPE = 'U' THEN
', @identityrangemanagementoption = N''manual'',@vertical_partition = N''false'',
@ins_cmd = N''CALL sp_MSins_'+t.sch_owner+''+t.Name+
''', @del_cmd = N''CALL sp_MSdel_'+t.sch_owner+''+t.Name+''',
@upd_cmd = N''SCALL sp_MSupd_'+t.sch_owner+''+t.Name+''''
ELSE ''
END
+';'
FROM #t t
PRINT 'Now running sp_replicationdboption'
PRINT @sp_replicationdboption
EXEC(@sp_replicationdboption)
PRINT 'Now running sp_addpulication'
PRINT @sp_addpulication
EXEC(@sp_addpulication)
IF @allow_initialize_from_backup = 'false'
BEGIN
PRINT 'Now running sp_addpulication_snapshot and starting snapshot'
PRINT @sp_addpublication_snapshot
EXEC(@sp_addpublication_snapshot)
EXEC(@sp_startpublication_snapshot)
END
PRINT 'Now running sp_addarticles'
PRINT @sp_addarticle
EXEC(@sp_addarticle)
-- exec sp_droppublication @publication = N'Products'
END TRY
BEGIN CATCH
IF @@trancount > 0
ROLLBACK
DECLARE @ERROR_SEVERITY INT, @ERROR_STATE INT, @ERROR_MESSAGE NVARCHAR(4000)
SELECT @ERROR_SEVERITY = ERROR_SEVERITY(), @ERROR_STATE = ERROR_STATE(), @ERROR_MESSAGE = ERROR_MESSAGE()
RAISERROR(@ERROR_MESSAGE, @ERROR_SEVERITY, @ERROR_STATE)
END CATCH
END
GO
and finally execute
EXEC CreatePublicationForDB 'TestPublication'
-- drop replication in case you want to run the above again.
exec TestPublication.dbo.sp_droppublication @publication = 'TestPublication'
exec TestPublication.dbo.sp_replicationdboption @dbname = 'TestPublication', @optname = 'publish', @value = 'false'
-- cleanup database
DROP DATABASE TestPublication
3条答案
按热度按时间xghobddn1#
Sorry, old post I know, but I ran into a very similar situation and got around it. I haven't found a workable solution anywhere else. I'm including my experience to help others.
Summary of my situation is that I have an msbuild process running a series of scripts from a manifest file (text file with a series of script names) within a transaction. The scripts that were intended to create and configure agent jobs always died with the same error. (invalid column name "file_exists")
Procs used in my failing script(s):
Commenting out the call to msdb.dbo.sp_add_jobstep allowed the script to complete.
I do have SQL command variables in the form @database_name=N'$(DatabaseName)' in the script as well. This led to some misdirected efforts to try to use escape macros as mentioned in the "Important" note under [ @command= ] 'command' on the documentation for sp_add_jobstep.
https://msdn.microsoft.com/en-us/library/ms187358.aspx
If I run the build up to, but not including, the job creation script and start over, it succeeds.
What I found, after much trial and error, was that, even though the procs are qualified as being in [MSDB], unless I actually included a USE statement, the process fails. By beginning the script with "USE [MSDB] GO" and then switching back to my build target (i.e. USE [MyBuildDB] GO), I no longer get the error.
My agent jobs create as expected, and several scripts within the build run without error.
bf1o4zei2#
It's hard to say what the problem is without seeing all of the code and having the schema. I'd recommend not creating a wrapper to create publication(s). The create publication scripts can be saved and executed on demand when needed - eliminating the need for a wrapper.
t0ybt7op3#
I have procedure which create many SQL agent jobs. And sometimes i have problem with next ERROR with calling msdb.dbo.sp_add_jobstep - Return
ERROR: Invalid column name 'file_exists'
After using "Begin try" i got procedure of error msdb.dbo.sp_verify_subsystems And this procedure has next code:I suggest that in parallel session some procedure use the same name #t with another column names.
In procedure
msdb.dbo.sp_verify_subsystems
i changed temp table name from#t
to some unique#tsp_verify_subsystems
it's helped me.
P.S. Don't use temp table name such
#t