So many people have told me how much they like DMX - the fact that they can use a query language to create, train, and query mining models is simply unprecedented in the data mining world.  And they love it.

 Until.....

Until, that is, they decide to go whole hog on DMX and implement their entire solution using ONLY DMX.  Wow!  What a great idea!  I'll create a new database just for mining, and then I'll use DMX to create a mining structure, then use ALTER MINING STRUCTURE to add all my models, and then train using INSERT INTO.

 Oh, frizznet!  I can't INSERT INTO - I don't have a datasource.

How do you create a datasource with DMX?

YOU DON'T!

DMX lacks any syntax for creating or managing datasources, even though the language depends on datasources for all external data access (unless you want to open that giant security hole that is OPENROWSET, but that's a story for another blog post...).

However, not all is lost.  It is fairly trivial to create a stored procedure that will take a datasource definition and create it for you from a command interface.  In fact, it's so easy, because all you have to do is copy and paste the source code below.

 [SafeToPrepare(true)]
public void CreateDataSource(string DataSourceName, string ConnectionString,
                         string sImpersonationMode, string Account, string Password)
{
      if (Context.ExecuteForPrepare)
              return;

      // Connect to the calling session
      Microsoft.AnalysisServices.Server svr = new Microsoft.AnalysisServices.Server();
      svr.Connect(
"*");

      // Get the current database
      Database db = svr.Databases.GetByName(Context.CurrentDatabaseName);

      // Create a new datasource and set connection string
      DataSource ds = db.DataSources.AddNew(DataSourceName, DataSourceName);
      ds.ConnectionString = ConnectionString;
      
      // Set the impersonation info
      bool FoundMode = false;
      foreach (ImpersonationMode mode in Enum.GetValues(typeof(ImpersonationMode)))
      {
          if (mode.ToString() == sImpersonationMode)
          {
              FoundMode =
true;
              ds.ImpersonationInfo =
new ImpersonationInfo(mode, Account, Password);
              break;
          }
       }
      if (!FoundMode)
          throw (new SystemException("Invalid Impersonation Mode"));

      // Update the server with the new datasource
      ds.Update();
}

When you build a project with this code, you need to include AMO as well as Server ADOMD.Net references.  When deploying the assembly to the server, you need to make the assembly access "Unrestricted" or it will throw exceptions when trying to execute the AMO code.

After you have successfully built and deployed the stored procedure you can call it like this

CALL MySproc.CreateDataSource('MyDataSourceName','
                   Provider=SQLNCLI;Location=localhost;Initial Catalog=MyDatabase','ImpersonateCurrentUser','','')

And there you have it - closed the datasouce hole in DMX in 100 lines of code or less.  Of course, if you're adventurous, you can add other management functions to add permissions to datasources, delete them, whatever you want!

Enjoy!