Hi! Merge replication. From Sql Server 2000 SP4 to MSDE SP4 Using FTP and compressing the initial snapshot. I recently added a user defined function as a computed column on a table. When the anonymous subscriber is sychronizing the initial snapshot, it errors out saying that the user defined function does not exist. I am assuming that merge replication is not smart enough to execute the UDF first. I looked at the cab file, and if the numbers show the order of sequence, then the UDF is a higher number then the table that uses it. If I am on the right track, is the workaround a seperate publication just for UDF's? Here was the error: The following replication error(s) occurred: The schema script '\\w2kserver\repldata\ftp\W2KSERVER_Test_Pub\20050531213058\Bit_Report_2511.sch' could not be propagated to the subscriber. Extracted file 'Bit_Report_2511.sch' Invalid object name 'dbo.udf_Bit_Rate'.
It looks worse then I thought. My function in table B of the computed column uses data from another table. So the function needs to be created after table A but before table B. I also looked at how the UDF is handled from a drop perspective and it won't work either. Replication stuffs the drop command in a pre-processing step. Well if a table that still uses it exists in the subscriber database, it won't be dropped! May someone confirm computed columns are not supported by replication in sql server SP4 so that I can figure out a new plan? Anyone know a managable workaround? Or should I just abandon computed columns altogether. Thanks, Buzz [quoted text, click to view] "Buzz" wrote: > Hi! > > Merge replication. > > From Sql Server 2000 SP4 to MSDE SP4 > > Using FTP and compressing the initial snapshot. > > I recently added a user defined function as a computed column on a table. > > When the anonymous subscriber is sychronizing the initial snapshot, it > errors out saying that the user defined function does not exist. > > I am assuming that merge replication is not smart enough to execute the UDF > first. I looked at the cab file, and if the numbers show the order of > sequence, then the UDF is a higher number then the table that uses it. > > If I am on the right track, is the workaround a seperate publication just > for UDF's? > > Here was the error: > The following replication error(s) occurred: > The schema script > '\\w2kserver\repldata\ftp\W2KSERVER_Test_Pub\20050531213058\Bit_Report_2511.sch' could not be propagated to the subscriber. > Extracted file 'Bit_Report_2511.sch' > Invalid object name 'dbo.udf_Bit_Rate'.
Buzz, there are a few options: put the UDF in a pre-snapshot script use sp_addscriptexec use a separate publication use SQL 2005 where you can specify the processing order of articles In my case I like to use a separate publication. Unlike SQL 2005 there is no way in SQL 2000 that changes to the UDF will be automatically propagated unlike. If it does change, I have the simple matter of reinitializing the UDF publication, and of knowing when it last occurred. Rgds, Paul Ibison SQL Server MVP, www.replicationanswers.com (recommended sql server 2000 replication book: http://www.nwsu.com/0974973602p.html)
Buzz, I just created this function and successfully replicated it: CREATE FUNCTION "test" () RETURNS int AS BEGIN declare @count int set @count = (select count(*) from xxx) return @count END However there's no table xxx on the subscriber (or publisher). Please can you push this subscription locally (no ftp but fileshares), and enable logging of the distribution agent to see if there's more info. Also, please run udf_Bit_Rate_0.sql manually on the initial subscriber to see if there is an error message - try this first. Rgds, Paul Ibison
Buzz, as UDFs use deferred name resolution, I think you can make things easy by ensuring the UDF is created before both tables? Rgds, Paul Ibison to [quoted text, click to view] "Buzz" <buzz@online.nospam> wrote in message news:2B39A755-AFF7-4939-A06A-15372A8BC3F8@microsoft.com... > Thanks for the detailed steps. > > However, I need to specify the order as my computed column on Table B uses > information from Table A. SQL 2005 is out as an option for me. > > I suppose I could try to exclude the calculated columns from the > publication > and add the computed columns to the tables after the initialization was > done > in a post-processing script. > > Ugly. > > Again, thanks for the ideas Paul, > > Buzz > > "Paul Ibison" wrote: > >> Buzz, >> there are a few options: >> put the UDF in a pre-snapshot script >> use sp_addscriptexec >> use a separate publication >> use SQL 2005 where you can specify the processing order of articles >> In my case I like to use a separate publication. Unlike SQL 2005 there is >> no >> way in SQL 2000 that changes to the UDF will be automatically propagated >> unlike. If it does change, I have the simple matter of reinitializing the >> UDF publication, and of knowing when it last occurred. >> Rgds, >> Paul Ibison SQL Server MVP, www.replicationanswers.com >> (recommended sql server 2000 replication book: >> http://www.nwsu.com/0974973602p.html) >> >> >>
Thanks for the detailed steps. However, I need to specify the order as my computed column on Table B uses information from Table A. SQL 2005 is out as an option for me. I suppose I could try to exclude the calculated columns from the publication and add the computed columns to the tables after the initialization was done in a post-processing script. Ugly. Again, thanks for the ideas Paul, Buzz [quoted text, click to view] "Paul Ibison" wrote: > Buzz, > there are a few options: > put the UDF in a pre-snapshot script > use sp_addscriptexec > use a separate publication > use SQL 2005 where you can specify the processing order of articles > In my case I like to use a separate publication. Unlike SQL 2005 there is no > way in SQL 2000 that changes to the UDF will be automatically propagated > unlike. If it does change, I have the simple matter of reinitializing the > UDF publication, and of knowing when it last occurred. > Rgds, > Paul Ibison SQL Server MVP, www.replicationanswers.com > (recommended sql server 2000 replication book: > http://www.nwsu.com/0974973602p.html) > >
Hi Paul, I was trying to test your theory but I ran into this error: The schema script '\\W2KSERVER\ReplData\ftp\W2KSERVER_Test_Pub\20050601101419\udf_Bit_Rate_0.sql' could not be propagated to the subscriber. I am using FTP and compression. I checked the snapshot.cab file and it is indeed in there. Other newsgroup posting talk about security access but since it is in the ..cab file with the rest of the files, I would think that is not the problem. Thanks, Buzz [quoted text, click to view] "Paul Ibison" wrote: > Buzz, > as UDFs use deferred name resolution, I think you can make things easy by > ensuring the UDF is created before both tables? > Rgds, > Paul Ibison > > > > to > "Buzz" <buzz@online.nospam> wrote in message > news:2B39A755-AFF7-4939-A06A-15372A8BC3F8@microsoft.com... > > Thanks for the detailed steps. > > > > However, I need to specify the order as my computed column on Table B uses > > information from Table A. SQL 2005 is out as an option for me. > > > > I suppose I could try to exclude the calculated columns from the > > publication > > and add the computed columns to the tables after the initialization was > > done > > in a post-processing script. > > > > Ugly. > > > > Again, thanks for the ideas Paul, > > > > Buzz > > > > "Paul Ibison" wrote: > > > >> Buzz, > >> there are a few options: > >> put the UDF in a pre-snapshot script > >> use sp_addscriptexec > >> use a separate publication > >> use SQL 2005 where you can specify the processing order of articles > >> In my case I like to use a separate publication. Unlike SQL 2005 there is > >> no > >> way in SQL 2000 that changes to the UDF will be automatically propagated > >> unlike. If it does change, I have the simple matter of reinitializing the > >> UDF publication, and of knowing when it last occurred. > >> Rgds, > >> Paul Ibison SQL Server MVP, www.replicationanswers.com > >> (recommended sql server 2000 replication book: > >> http://www.nwsu.com/0974973602p.html) > >> > >> > >> > >
Hi Paul, You've been very helpful, it's great to get assistance on this. I ran udf.sql against the subscriber. It errored out on the DROP which I normally don't care about. But that got me thinking, I checked the Merge Agent Session History and it said the call to OSQL for the file bombed. I changed the straight DROP into a IF EXISTS on the sysobjects to avoid the error and the synchronization works! 1) However, from a maintenance perspective in production, if I find a bug in the function, I'll have to right a more complex script that drops all dependant table columns, alters the function and then adds back the columns. 2) The other method I've worked through is that I can create the function in database 2, then I create a wrapper function in database 1 to call it, then the computed column calls the wrapper in database 1. I can rebuild my functions in database 2 to my hearts desire as long as I keep the function interface the same. Then I can use a simple publication to move new function changes. The ability to easily fix the guts of the function when its out in the field I think has value. I have never gone to production with Sql Server or Replication so I was wondering what the best practice was? Thanks, Buzz [quoted text, click to view] "Paul Ibison" wrote: > Buzz, > I just created this function and successfully replicated it: > > CREATE FUNCTION "test" () > RETURNS int AS > BEGIN > declare @count int > set @count = (select count(*) from xxx) > return @count > END > > However there's no table xxx on the subscriber (or publisher). > > Please can you push this subscription locally (no ftp but fileshares), and > enable logging of the distribution agent to see if there's more info. Also, > please run udf_Bit_Rate_0.sql manually on the initial subscriber to see if > there is an error message - try this first. > > Rgds, > Paul Ibison > >
Buzz, I'll test this, but I don't see any reason why you can't use sp_addscriptexec with an ALTER FUNCTION statement in it. Cheers, Paul Ibison
Hi Paul, Just with my limited experience with computed columns, once the function is part of a table, if I execute an ALTER, I get: Cannot ALTER 'udfw_Bit_Rate' because it is being referenced by object 'Bit_Report'. This restriction is outside of replication. However, if there was a bug in a function that needed fixing, because the table is part of replication, it would be really complex to get the steps right to drop the computed column from the table, alter the function, and then re-add the computed column back to the table (and still not screw up replication with all those people out on laptops just wanting to synchronize data). So I simplified my process a bit. Instead of creating a seperate database, I just create my real functions prefixed by udf. I think include them as articles in the publication. I then create wrapper functions prefixed by udfw that the tables reference for their computed columns. Those udfw functions are then part of the pre-processing script of the snapshot. I know I am stuck with the public interface of the udfw but at least now I have abstracted the table being tied to the true function. And if I need more information in that function, I can just select from the current row (hmmmm... maybe as a best practice, I will always pass in the key fields of the record to the function.) One thing I have to test now is if I change the udf, how does it get synchronized with existing subscribers without forcing them to reinitialize and thus loose all of their data (so I'm told). Thanks, Buzz [quoted text, click to view] "Paul Ibison" wrote: > Buzz, > I just created this function and successfully replicated it: > > CREATE FUNCTION "test" () > RETURNS int AS > BEGIN > declare @count int > set @count = (select count(*) from xxx) > return @count > END > > However there's no table xxx on the subscriber (or publisher). > > Please can you push this subscription locally (no ftp but fileshares), and > enable logging of the distribution agent to see if there's more info. Also, > please run udf_Bit_Rate_0.sql manually on the initial subscriber to see if > there is an error message - try this first. > > Rgds, > Paul Ibison > >
Buzz, I quite like the abstraction solution. I hadn't realised that computed columns are schema bound to the UDF, once related. This makes sense, but I didn't realize this was mandatory - I'd like to take more of a look at this tomorrow. For your changes to the 'UDF' functions - these could be propagated using sp_addscriptexec and without reinitialization. Rgds, Paul Ibison SQL Server MVP, www.replicationanswers.com (recommended sql server 2000 replication book: http://www.nwsu.com/0974973602p.html)
Hi Buzz, It is rather unfortunate that replication of computed columns on udf dependencies is quite broken in SQL2000, the only workarounds that I can think of are: 1) Put the udf definition in a pre-snapshot script 2) Filter out computed columns depending on udfs I must say that neither of the above is a particularly acceptable solutions. But at the risk of getting myself into trouble, this and a bunch other dependency problems are addressed in SQL2005. -Raymond [quoted text, click to view] "Buzz" wrote: > Hi Paul, > > Just with my limited experience with computed columns, once the function is > part of a table, if I execute an ALTER, I get: > > Cannot ALTER 'udfw_Bit_Rate' because it is being referenced by object > 'Bit_Report'. > > This restriction is outside of replication. However, if there was a bug in a > function that needed fixing, because the table is part of replication, it > would be really complex to get the steps right to drop the computed column > from the table, alter the function, and then re-add the computed column back > to the table (and still not screw up replication with all those people out on > laptops just wanting to synchronize data). > > So I simplified my process a bit. Instead of creating a seperate database, I > just create my real functions prefixed by udf. I think include them as > articles in the publication. I then create wrapper functions prefixed by udfw > that the tables reference for their computed columns. Those udfw functions > are then part of the pre-processing script of the snapshot. > > I know I am stuck with the public interface of the udfw but at least now I > have abstracted the table being tied to the true function. And if I need more > information in that function, I can just select from the current row > (hmmmm... maybe as a best practice, I will always pass in the key fields of > the record to the function.) > > One thing I have to test now is if I change the udf, how does it get > synchronized with existing subscribers without forcing them to reinitialize > and thus loose all of their data (so I'm told). > > Thanks, > Buzz > > "Paul Ibison" wrote: > > > Buzz, > > I just created this function and successfully replicated it: > > > > CREATE FUNCTION "test" () > > RETURNS int AS > > BEGIN > > declare @count int > > set @count = (select count(*) from xxx) > > return @count > > END > > > > However there's no table xxx on the subscriber (or publisher). > > > > Please can you push this subscription locally (no ftp but fileshares), and > > enable logging of the distribution agent to see if there's more info. Also, > > please run udf_Bit_Rate_0.sql manually on the initial subscriber to see if > > there is an error message - try this first. > > > > Rgds, > > Paul Ibison > > > >
Don't see what you're looking for? Try a search.
|