SSAS: Executing Arbitrary SQL queries

I had a question a little while ago via my blog about possibly using a rowset action to execute a SQL query against a specified table. Although a rowset action will allow you to enter a SQL query, such a query is still executed against the current cube and only the subset of SQL supported by SSAS can be used. Basically the rowset action just returns a flattened result set.

However what would be possible would be to write a.Net stored procedure and use that to execute your SQL query. The code itself is really simple, the whole procedure only takes a few lines:

using System; using System.Data; using System.Data.OleDb;

namespace ASSP { public class SQLQuery { public static DataTable ExecuteSQL(string connectionString, string sql) { OleDbConnection conn = new OleDbConnection(connectionString);

DataTable dt = new DataTable("Results"); OleDbDataAdapter da = new OleDbDataAdapter(sql, conn); da.Fill(dt); return dt; } } }

(http://11011.net/software/vspaste

And with this small amount of code you can execute any query that you like using the CALL statement

eg.

call assp.ExecuteSql( "provider=sqlncli;server=localhost;database=AdventureWorksDW;trusted_connection=yes" ,"Select * from DimCurrency");

Which is really cool if you want to do your own drillthrough or return an arbitrary recordset (assuming that your client application supports rowset actions). By you can actually execute more than just any query, you can actually execute any statement.

So you can paste the following set of statements into SSMS and run them.

call assp.ExecuteSql( "provider=sqlncli;server=localhost;database=AdventureWorksDW;trusted_connection=yes" ,"Create TABLE myTable (id int)"); GO call assp.ExecuteSql( "provider=sqlncli;server=localhost;database=AdventureWorksDW;trusted_connection=yes" ,"INSERT INTO myTable VALUES(1)"); GO call assp.ExecuteSql( "provider=sqlncli;server=localhost;database=AdventureWorksDW;trusted_connection=yes" ,"SELECT * FROM myTable"); GO call assp.ExecuteSql( "provider=sqlncli;server=localhost;database=AdventureWorksDW;trusted_connection=yes" ,"DROP TABLE myTable");

Even though I can only see this technique being used for SELECT statements, you can basically do anything you like in the database provided you have the appropriate rights. Pretty powerful, initially I thought that this might be too powerful to put into the on codeplex, but the more I think about it the more I think I was being paranoid, so I have checked this code into the ASStoredProcedure project. With the default deployment options a user can only perform operations that they already have rights to do anyway. It's really only if the assembly is deployed to run under the service account and if the service account has more rights than your end users that there is any risk of someone running a statement with elevated privileges.

Ultimately I'm not sure how directly useful this simple procedure will be, but I think it will provide a starting point from which more sophisticated routines can be developed using some of the other techniques demonstrated in other functions in ASSP. I'd be interested to hear comments from anyone who ends up adapting this routine.

Update 19 Jun: I removed the "ReadOnly=1" from the end of the connection string - as it was not actually doing anything

This article is part of the GWB Archives. Original Author: Darren Gosbell

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.