我创建了一个包装器存储过程来为SQL Server 2008 Standard Edition SP3的事务复制创建发布。但是当我执行该过程时,我收到以下错误。 “file_exists”列不是用户定义的。这个错误对我没有任何意义。这适用于Dev环境,但相同的代码不适用于测试环境。据我所知,Dev和Test是完全相同的。我还试图明确设置选项,使它们成为5496(SELECT @@ OPTIONS)。非常感谢任何帮助。
- 错误
Msg 50000, Level 16, State 1, Procedure CreatePublicationForDB, Line 161
Invalid column name 'file_exists'.
- 开始编写脚本
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
最后执行
EXEC CreatePublicationForDB 'TestPublication'
- 如果您想再次运行上述内容,请删除复制。
exec TestPublication.dbo.sp_droppublication @publication = 'TestPublication'
exec TestPublication.dbo.sp_replicationdboption @dbname = 'TestPublication', @optname = 'publish', @value = 'false'
- 清理数据库
DROP DATABASE TestPublication
答案 0 :(得分:3)
对不起,老帖子我知道,但我遇到了一个非常相似的情况并绕过它。我还没有在其他任何地方找到可行的解决方案。我包括我的经验,以帮助他人。
我的情况总结是我有一个msbuild进程,它从一个事务中的清单文件(带有一系列脚本名称的文本文件)运行一系列脚本。用于创建和配置代理作业的脚本始终以相同的错误消失。 (列名“file_exists”无效)
我失败的脚本中使用的过程:
msdb.dbo.sp_add_category
msdb.dbo.sp_add_job
msdb.dbo.sp_add_jobstep
msdb.dbo.sp_update_job
msdb.dbo.sp_add_jobschedule
msdb.dbo.sp_add_jobserver
注释掉对msdb.dbo.sp_add_jobstep的调用,可以完成脚本。
我在脚本中也有@ database_name = N'$(DatabaseName)'形式的SQL命令变量。这导致了一些错误的尝试,试图使用转义宏,如sp_add_jobstep文档中[@ command =]'command'下的“重要”注释中所述。
https://msdn.microsoft.com/en-us/library/ms187358.aspx
如果我运行构建到但不包括作业创建脚本并重新开始,则会成功。
经过多次试验和错误后,我发现,即使procs被认定为[MSDB],除非我实际包含了USE语句,否则该过程失败。通过以“USE [MSDB] GO”开始脚本,然后切换回我的构建目标(即USE [MyBuildDB] GO),我不再收到错误。
我的代理作业按预期创建,并且构建中的多个脚本运行时没有错误。
答案 1 :(得分:0)
如果没有看到所有代码并拥有架构,很难说问题是什么。我建议不要创建一个包装来创建出版物。创建发布脚本可以在需要时保存并按需执行 - 无需使用包装器。