SQL Server: Create a linked server from an on-premise SQL Server* to SQL Azure

  • SQL Server 2008 onwards

The use of SQL Server’s sp_addlinkedserver can be a little arcane. I recently needed to connect from an on-premise SQL Server to SQL Azure for the purpose of querying and downloading data to a reporting server, and there a couple of things to note.

One is that you should ensure that data is encrypted on the wire (* and also when connecting to remote servers from SSMS).

 

The other is that you have to may specify the server name as a DNS name (depending on the client connection library you are using). This is the case if you receive this error message:

Server name cannot be determined.  It must appear as the first segment of the server’s dns name (servername.database.windows.net).  Some libraries do not send the server name, in which case the server name must be included as part of the user name (username@servername).  In addition, if both formats are used, the server names must match. “

Here’s the working TSQL script I used:

 

— If linked server already exists, drop it and any associated logins.

begin try

    exec sp_dropserver ‘LocalLinkedServername’, ‘droplogins’

end try

begin catch

end catch

 

— Create the linked server: 

EXEC sp_addlinkedserver

    @server     = ‘LocalLinkedServername’,

    @srvproduct = N’Any’,

    @provider   = ‘SQLNCLI’,

    @datasrc    = ‘??????????.database.windows.net’, — Azure server name

    @location   = ,

    @provstr    = N’Encrypt=yes;’,       — * Important!

    @catalog    = ‘RemoteDatabaseName’;  — remote(Azure) database name

go

 

— Create the login credentials for the linked server 

EXEC sp_addlinkedsrvlogin

    @rmtsrvname  = ‘LocalLinkedServername’,

    @useself     = ‘false’,

    @rmtuser     = ‘remotesqlusername@??????????.database.windows.net’,

    @rmtpassword = ‘remote password’;

go

 

 

EXEC sp_serveroption ‘LocalLinkedServername’, ‘rpc out’, ‘true’;

go

 

— Don’t elevate to distributed transactions

EXEC sp_serveroption ‘LocalLinkedServername’, ‘remote proc transaction promotion’, ‘false’;

go

 

—- Finally, check you can access remote data via your linked server:

select top 100 *

from [LocalLinkedServerName].[RemoteDatabaseName].[RemoteSchemaName].[RemoteTableName];

go

 

 

 

Another issue you might run into is if you have SQL Database auditing turned on in Azure, Azure wants all connections to be from a secure connection string, and if you run the above script from certain versions of SSMS (I believe SQL Server 2012 and below but not verified) then you might get an error saying only connections with secure connection string are allowed (despite a secure connection being specified). The fix is easy, change

myServerName.database.windows.net

to

myServerName.database.secure.windows.net

Keep in mind that prior to SQL Server 2012 SP1, remote server statistics won’t be able to be used to determine query plans unless admin credentials are used (not a good idea!). Prior to SQL Server 2012 SP1 there is a workaround shown here: SQL Server Linked Servers and Remote Statistics

 

Refs.:

TOP 3 PERFORMANCE KILLERS FOR LINKED SERVER QUERIES

SSAS: The Measures cube either does not exist or has not been processed

If you are attempting to deploy your existing SQL Server Analysis Services cube with calculation changes and get the following (not very helpful!) error:

The Measures cube either does not exist or has not been processed

then you probably forgot a CURRENTCUBE prefix on one or more of your MDX Create Member statements:

CREATE MEMBER CURRENTCUBE.Measures.[MyMeasure] AS
^^^^^^^^^^^

SQL Server Agent Job Visualisation: SQLjobvis

SQL Server must be older than 20 years and yet it still has no agent job schedule visualiser, despite the fact it has been asked for many times. How can that be? Go figure…

I needed one at work recently to identify schedule clashes, so I thought “I wonder how hard it would be to write something fairly basic”. Then programmer laziness swiftly kicked in and the next thought was “If this problem is a pain for so many, then someone must have written something already…?”

And of course, they have: SQLjobvis

It’s basic, simple, works great, and it’s free!

It instantly identifies:

  • Failures
  • Long-running jobs
  • Multiple jobs running simultaneously

    Brilliant!

  • Office 2013 64 bit Setup

    I’ve used every version of Microsoft Office pretty much since it came out. I currently have the 32 bit version of Office Pro 2010 installed. Attempting to install the 64 bit version of Office 2013 to evaluate Excel’s Power View results in:

    image

    Wouldn’t it be nice if it had the option to do this for me and migrate all my settings?!? Especially since I don’t recall there being a 64 bit version of Office 2010 on release (or was it just that it had issues with drivers and add-ins?).

    SQL Fiddle

    No, it’s not Uncle Ernie!

    SQL Fiddle is a very useful online tool for evaluating TSQL against a plethora of database engines (like jsFiddle does for javascript / jQuery), written by Jake Feasel

    I found JS Fiddle to be a great tool for answering javascript / jQuery questions, but I also found that there was nothing available that offered similar functionality for the SQL questions. So, that was my inspiration to build this site. Basically, I built this site as a tool for developers like me to be more effective in assisting other developers.

    It currently supports these database engines (in various versions): MySQL, PostgreSQL, MS SQL Server, Oracle, and SQLite

    .NET Regex: Character Class Subtraction

    You’ve heard of a positive match character group [] and a negative match character group [^]. But did you know there is also a Character Class Subtraction? I didn’t. It’s supported in .NET but not in the majority of RegEx flavours.

    A character class subtraction expression has the following form:

              [base_group – [excluded_group]]

    The square brackets ([]) and hyphen (-) are mandatory. The base_group is a positive or negative character group as described in the Character Class Syntax table. The excluded_group component is another positive or negative character group, or another character class subtraction expression (that is, you can nest character class subtraction expressions).

    For example, suppose you have a base group that consists of the character range from “a” through “z”. To define the set of characters that consists of the base group except for the character “m”, use [a-z-[m]]. To define the set of characters that consists of the base group except for the set of characters “d”, “j”, and “p”, use [a-z-[djp]]. To define the set of characters that consists of the base group except for the character range from “m” through “p”, use [a-z-[m-p]].

    Using this format, the pattern

    ^[\w-[v123]]$

    can be used in .NET to match all alphanumeric characters (any word character) excluding the letter v and numbers 123. 

    The MSDN page for the .NET Regex definitions doesn’t seem to appear high in the search indexes, so bookmarking here for my future reference: Character Classes in Regular Expressions

    This is useful for comparing Regex capabilities in different languages: regex flavor comparison chart

    SQL Diagnostic Runner Updated

    Thanks to Todd who reported a bug when connecting with username and password (I messed up the connection string).

    I’ve uploaded an updated version (v1.0.4.13057) which you can download from the links below (or from any of the previous posts):

    SQLDiagCmd.zip

    SQLDiagUI.zip

    [Servername will now take a semi-colon separated list of servers to run against, but with the limitation of using the same credentials and diagnostic script.]

    Parsing Command Line Arguments

    If you want a full blown Command Line Parser then there are several good options available:

    [I used the Command Line Parser Library recently in the SQL Diagnostic Runner I wrote.]

    If you just want a very basic parser, supporting simple options in the format  /argname:argvalue  then you could use this:

    /// 
    /// Very basic Command Line Args extracter
    /// Parse command line args for args in the following format:
    /// /argname:argvalue /argname:argvalue ...
    ///

    public class CommandLineArgs
    {
    private const string Pattern = @"\/(?\w+):(?.+)";
    private readonly Regex _regex = new Regex(Pattern, RegexOptions.IgnoreCase|RegexOptions.Compiled);
    private readonly Dictionary _args = new Dictionary();

    public CommandLineArgs()
    {
    BuildArgDictionary();
    }

    public string this[string key]
    {
    get { return _args.ContainsKey(key) ? _args[key] : null; }
    }

    public bool ContainsKey(string key)
    {
    return _args.ContainsKey(key);
    }

    private void BuildArgDictionary()
    {
    var args = Environment.GetCommandLineArgs();
    foreach (var match in args.Select(arg => _regex.Match(arg)).Where(m => m.Success))
    {
    try
    {
    _args.Add(match.Groups["argname"].Value, match.Groups["argvalue"].Value);
    }
    // Ignore any duplicate args
    catch (Exception) {}
    }
    }
    }

    Largest .NET Object….

    In .NET versions prior to .NET 4.5, the largest allocation for any single object is 2GB.

    On 64-bit platforms, in .NET versions 4.5 and greater, it is possible to enable the allocation of arrays that are larger than 2 GB in total size (but NOTE this does not change other limits on object size or array size):

    • The maximum number of elements in an array is UInt32MaxValue.

    • The maximum index in any single dimension is 2,147,483,591 (0x7FFFFFC7) for byte arrays and arrays of single-byte structures, and 2,146,435,071 (0X7FEFFFFF) for other types.

    • The maximum size for strings and other non-array objects is unchanged.

    The default setting is not enabled.

    You can enable this feature by using the gcAllowVeryLargeObjects element in your application configuration file:



    <gcAllowVeryLargeObjects enabled="true" />


    Before enabling this feature, ensure that your application does not include unsafe code that assumes that all arrays are smaller than 2 GB in size. For example, unsafe code that uses arrays as buffers might be susceptible to buffer overruns if it is written on the assumption that arrays will not exceed 2 GB.

    Ref.