|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionSQL Server presently does not provide option to generate script for linked servers on an existing instance it provides for other objects which we see as "Generate SQL Scripts" on context menus. The tool provided in this article creates script for linked servers and gives an option to either save the script to a file or run it immediately on another server. The script generated uses undocumented SQL Server extended stored procedures to access registry and can only be used by a sysadmin. There are number of ways to create this script. I found SQLDMO very useful because of the ease with which we can traverse through the SQLDMO objects and convert the properties into SQL statements. The same effort with any other way, like using ADO or stored procedure calls, would have taken more lines of code and complicated the programming logic. One problem with SQLDMO is that it does not have the "Disallow Adhoc Access" provider option in the Using the toolScreen shot below shows the tool in action:
To run the program:
Code DetailsA reference to Microsoft SQLDMO Object Library under COM libraries is added to the project references, and a foreach (LinkedServer2 ls in sqlserver.LinkedServers)
{
........
scriptText += "sp_addlinkedserver '" + ls.Name + "','" + ls.ProductName
Next, the logins used by the linked servers are scripted by the following code segment. We use a helper function // script the linked server logins
foreach (LinkedServerLogin login in ls.LinkedServerLogins)
{
scriptText += ("sp_addlinkedsrvlogin '" + ls.Name + "','" +
((login.Impersonate)? "true" : "false") + "',"
+ GetSQLStringValue(login.LocalLogin)
+ "," + GetSQLStringValue(login.RemoteUser) +
"," + PASSWORD_STRING + "\ngo\n");
}
After this, the linker server options are scripted by the code shown below. It is interesting to note the difference between the Connection Timeout and Query Timeout values passed to the // script the following Server Options -
// Collation Compatible, Data Access, RPC, RPC Out,
// Use Remote Collation, Collation Name,
// Connection Timeout, Query Timeout
scriptText += ("sp_serveroption '" + ls.Name + "','collation compatible',"
+ GetOnOffValue(ls.Options &
SQLDMO_SRVOPTION_TYPE.SQLDMOSrvOpt_CollationCompatible)
+ "\ngo\n");
scriptText += ("sp_serveroption '" + ls.Name + "','data access',"
+ GetOnOffValue(ls.Options &
SQLDMO_SRVOPTION_TYPE.SQLDMOSrvOpt_DataAccess)
+ "\ngo\n");
scriptText += ("sp_serveroption '" + ls.Name + "','rpc',"
+ GetOnOffValue(ls.Options & SQLDMO_SRVOPTION_TYPE.SQLDMOSrvOpt_RPC)
+ "\ngo\n");
scriptText += ("sp_serveroption '" + ls.Name + "','rpc out',"
+ GetOnOffValue(ls.Options & SQLDMO_SRVOPTION_TYPE.SQLDMOSrvOpt_RPC_out)
+ "\ngo\n");
scriptText += ("sp_serveroption '" + ls.Name + "','use remote collation',"
+ GetOnOffValue(ls.Options &
SQLDMO_SRVOPTION_TYPE.SQLDMOSrvOpt_UseRemoteCollation)
+ "\ngo\n");
scriptText += ("sp_serveroption '" + ls.Name + "','collation name',"
+ GetSQLStringValue(ls.CollationName) + "\ngo\n");
scriptText += ("sp_serveroption '" + ls.Name + "','connect timeout',"
+ ls.ConnectTimeout + "\ngo\n");
scriptText += ("sp_serveroption '" + ls.Name + "','query timeout','"
+ ls.QueryTimeout + "'\ngo\n");
At the end of the method, the Provider Options are scripted. It should be noted that these options are at the provider level and not at the linked server level. I.e., we may be using the same provider for a number of linked servers. That is why it is enough if we script the options only once for every provider. The It should be noted that these provider options are stored by SQL Server in the registry under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Providers\PROVIDER key as values. The One point to be noted - I do not know why SQLDMO does not have the "Disallow Adhoc Access" option in the Also, to overcome this limitation, we can use a private string GetProviderOptionScript(SQLDMO_SRVOPTION_TYPE options,
SQLDMO_SRVOPTION_TYPE check,
string value_name,
string provider)
{
string optionString = "exec master.."
+ (((options|check) == 0)?"xp_regdeletevalue ":"xp_regwrite ")
+ @"'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\MSSQLServer\Providers\"
+ provider + "','" + value_name + "'"
+ (((options|check) == 0)? "" : ",'REG_DWORD',1");
return optionString + "\ngo\n";
}
private void OnScript(object sender, System.EventArgs e)
{
.......
.......
// script the Provider Options if the product is not "SQL Server"
// send them into registry directly
if (providersListForOptions.IndexOf(ls.ProviderName, 0) == -1)
{
scriptText += "\n-- Options for provider : " + ls.ProviderName
The rest of the code is self explanatory.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||