An Oldie but a Goodie by Laurie Voss about SQL, noSQL, ORM, and more: http://seldo.com/weblog/2010/07/12/in_defence_of_sql
I had a need to concatenate and comma separate some multi-row data into an array of values with each having an unknown number of elements, in other words, take a many to one parent-child relationship and collapse the many child rows into the one parent record and separate the child record values with a comma. In the past, my default method to solve this problem was to build a temporary table and then use a loop to iterate through a data set and append the elements by updating rows in the temporary table, or use a common table expression with anchor and recursive members. Recently I stumbled upon the “stuff” and “for xml” functions. I had seen these functions before but never took the time to understand their potential use. These function can be used to solve the problem mentioned.
T-SQL For XML (Path Mode)
Function Description: A SELECT query returns results as a rowset. You can optionally retrieve formal results of a SQL query as XML by specifying the FOR XML clause in the query. The FOR XML clause can be used in top-level queries and in sub queries. The top-level FOR XML clause can be used only in the SELECT statement. In sub queries, FOR XML can be used in the INSERT, UPDATE, and DELETE statements. It can also be used in assignment statements.
In a FOR XML clause, you specify one of these modes: RAW, AUTO, EXPLICIT, PATH. We will only use PATH for this exercise.
The PATH mode together with the nested FOR XML query capability provides the flexibility of the EXPLICIT mode in a simpler manner.
The EXPLICIT mode allows more control over the shape of the XML. You can mix attributes and elements at will in deciding the shape of the XML. It requires a specific format for the resulting rowset that is generated because of query execution. This rowset format is then mapped into XML shape. The power of EXPLICIT mode is to mix attributes and elements at will, create wrappers and nested complex properties, create space-separated values (for example, OrderID attribute may have a list of order ID values), and mixed contents.
I will not list the syntax for this function because it can get pretty complex very quickly for all of the options. Instead, you can see in the example I just use it to concatenate the rows into a comma separated array. Any other XML is basically ignored by passing in the argument “Path (”)”.
T-SQL Stuff Function
Function Description: The STUFF function inserts a string into another string. It deletes a specified length of characters in the first string at the start position and then inserts the second string into the first string at the start position.
Function Syntax: STUFF ( character_expression , start , length ,character_expression )
List database users and include all roles of which a user is a member, separated by comma.
Solution using Stuff and For XML
- “For XML” is used to collapse and concatenate the row data into a single array.
- “Stuff” is used to remove the leading comma.
- Note that we are using a correlated subquery when we reference “dp.principal_id” in order to limit our roles and role members to our database principals in the main outer query.
,STUFF(( SELECT ',' + CONVERT(VARCHAR(500),isnull(USER_NAME(mem.role_principal_id),''))
FROM sys.database_role_members mem
WHERE mem.member_principal_id = dp.principal_id
), 1, 1, '') AS Roles
from sys.database_principals dp
where type != 'R'
and name not in ('dbo','guest','INFORMATION_SCHEMA','sys','MS_DataCollectorInternalUser')
“Exciting news! Starting today, SQL Server 2014 Developer Edition is now a free download for Visual Studio Dev Essentials members (you will be prompted to sign in to Visual Studio Dev Essentials before you can download SQL Server 2014 Developer Edition). We are making this change so that all developers can leverage the capabilities that SQL Server 2014 has to offer for their data solution, and this is another step in making SQL Server more accessible. SQL Server Developer Edition is for development and testing only, and not for production environments or for use with production data.”
“SQL Server 2016 Developer Edition, when released later this year, will also be free. To learn more about the exciting new features in SQL Server 2016, read the datasheet.”
I have been struggling with creating a user who has read only access to an azure database and finally figured it out. The key is connecting to the right database in a new session when executing the t-sql commands. This is because you can not execute a “use” statement, change the database in the current session via the GUI, and you can not make named references to databases in your t-sql.
--OPEN NEW SESSION TO MASTER DB
CREATE LOGIN ReadOnlyLogin
WITH PASSWORD = 'ENTER STRONG PASSWORD'
CREATE USER ReadOnlyUser
FOR LOGIN ReadOnlyLogin
WITH DEFAULT_SCHEMA = dbo
--OPEN NEW SESSION TO YOUR AZURE DB
CREATE USER ReadOnlyUser FROM LOGIN ReadOnlyLogin;
EXEC sp_addrolemember 'db_datareader', 'ReadOnlyUser';
Validate user has read only permissions by connecting to database using these new credentials and executing something like “CREATE TABLE dbo.test (test datetime);”, which should return an error message indicating permission denied.
More information on managing database access and login security in azure: https://azure.microsoft.com/en-us/documentation/articles/sql-database-manage-logins/
I wanted to compare WiFi coverage of two different wireless access points and their various configurations in my house, and also check for dead spots. One quick and cheap way to do this that I have come across is using a free product called Ekahau HeatMapper.
Ekahau HeatMapper allows you to walk around your home or office and capture information about WiFi signals in various spots, and then the software aggregates this information into a banded topographical map.
Visit Streetwyze on Facebook: https://www.facebook.com/Streetwyze-442494669144227/
This code will drop the login and users for all databases for a provided user name. and reports on its progress. This only works where the user and login match. This script does not check if users own any objects.
DROP LOGIN AND USERS FOR ALL DBs IN A SERVER
Possible errors could be if a user is the owner of a database object.
SET NOCOUNT ON
DECLARE @Dropping_Windows_Logon_Name NVARCHAR(MAX) = N'starwars\amlegault' --SPECIFY USER TO DROP, typical format: domain\user
DECLARE @tbl_Databases TABLE (Name NVARCHAR(MAX))
DECLARE @Database_Name NVARCHAR(MAX)
DECLARE @SQL_Drop_Login NVARCHAR(MAX)
DECLARE @SQL_Drop_DB_Users NVARCHAR(MAX)
PRINT 'Begin Login and User Drop Procedure for Windows Logon Name ' + @Dropping_Windows_Logon_Name + ' on server ' + @@SERVERNAME
--DROP LOGIN FROM SERVER
PRINT CHAR(0x0D) + CHAR(0x0A) + 'Begin Server Principal Drop Procedure'
IF EXISTS (SELECT * FROM sys.server_principals WHERE name = @Dropping_Windows_Logon_Name)
SET @SQL_Drop_Login = 'DROP LOGIN [' + @Dropping_Windows_Logon_Name +']'
PRINT 'Server Principal Dropped'
PRINT 'Server Principal Found But Could Not Drop'
PRINT 'Server Principal Not Found'
--USER DROP PROCEDURE
PRINT CHAR(0x0D) + CHAR(0x0A) + 'Begin User Drop Procedure'
--LOAD DATABASE NAMES INTO TEMP TABLE TO USE FOR LOOP
INSERT INTO @tbl_Databases (Name)
FROM master.sys.databases WITH(NOLOCK)
--LOOP THROUGH EACH DATABASE AND DROP USER IF THEY EXIST
WHILE EXISTS (SELECT TOP 1 * FROM @tbl_Databases)
SET @Database_Name = (SELECT TOP 1 Name FROM @tbl_Databases)
SET @SQL_Drop_Login ='USE '+@Database_Name
+' IF EXISTS (SELECT * FROM sys.database_principals WHERE name = ''' + @Dropping_Windows_Logon_Name + ''' AND sys.database_principals.type = ''U'')
DROP USER [' + @Dropping_Windows_Logon_Name +']
PRINT '' Dropped User in '+@Database_Name+'''
PRINT '' User Found But Could Not Drop in '+@Database_Name+'''
ELSE PRINT '' User Not Found in '+@Database_Name+'''
DELETE FROM @tbl_Databases WHERE Name = @Database_Name
PRINT 'End User Drop Procedure'
PRINT CHAR(0x0D) + CHAR(0x0A) + 'End Login and User Drop Procedure for Windows Logon Name ' + @Dropping_Windows_Logon_Name + ' on server ' + @@SERVERNAME
SET NOCOUNT OFF
Checks all databases on a server for any users who do not have a correlated login, based on SID. Uses the undocumented command of sp_msforeachdb. You could put in a loop if you want to avoid this command.
DECLARE @orphan_users TABLE (Server NVARCHAR(MAX),DBName sysname, [user_name] sysname,type_desc nvarchar(60),default_schema_name sysname, create_date datetime, modify_date DATETIME, [sid] VARBINARY(85))
INSERT INTO @orphan_users (Server, DBname,[user_name],type_desc,default_schema_name,create_date,modify_date,[sid])
from sys.database_principals where type in (''G'',''S'',''U'')
and [sid] not in ( select [sid] from sys.server_principals where type in (''G'',''S'',''U'') )
and name not in (''dbo'',''guest'',''INFORMATION_SCHEMA'',''sys'',''MS_DataCollectorInternalUser'')'
SELECT * FROM @orphan_users
--WHERE user_name LIKE '%SomeUser%' /*optional*/
ORDER BY user_name
There is a feature in Power BI which allows you to connect to your google analytics data, and there is a new preview feature which allows publishing content to the web in an iframe. In this post I have combined both features together to display my website statistics to the web.
- Connect to Google Analytics: https://powerbi.microsoft.com/en-us/documentation/powerbi-content-pack-google-analytics/
- Publish to Web: https://powerbi.microsoft.com/en-us/blog/announcing-power-bi-publish-to-web/
Here is the result:
Note: PowerBI has trouble rendering in Chrome in some cases. If you are using Chrome and can not see the dashboard then try another browser. Hopefully Microsoft will resolve this problem.
I’ve been catching myself up on what Microsoft is doing lately regarding Business Intelligence. After spending days reading Microsoft documentation and testing some various configurations of Power BI, Gateway,Azure, and SSRS, I came across this video that goes over some history and then gets right into Power BI and some competing tools. I suspect Microsoft is working toward merging Power BI and SSRS based on some of their SQL Server public previews.