SQL Server security mechanism How to control what data users are able to view within their reports

SQL Server security mechanism How to control what data users are able to view within their reports

SQL Server security mechanism - How to control what data users are able to view within their reports

SQLShack

SQL Server training Español

SQL Server security mechanism – How to control what data are users able to view within their reports

January 8, 2015 by Steve Simon

Introduction

A few years back, a client asked me to implement a quick and dirty “security mechanism” to control what data the myriad of users were able to view within their reports. There were numerous tables with multiple columns and all departments (within the enterprise) had their data within these tables. SQLShack Industries has tasked us with creating a similar quick and dirty “security mechanism”. We shall attack this challenge by creating the necessary stored procedures (to extract the required data) and then utilize these stored procedures to render and consume the data within our reports.

Getting started

Opening SQL Server Management Studio we find our ‘YearlySales1’ table. This table contains the total monthly sales figures for two sales teams (Team1 and Team2). For the first portion of this exercise Team1 is ONLY permitted to view THEIR OWN data and Team2 THEIR OWN data. The raw data maybe seen below: Our first task is to construct a small security table called “SQLShackSecurity” (see below). The client has two department heads and both head major corporate teams (see below). Now that our infrastructure has been created, we are ready to create the necessary stored procedures to service the corporate reports. Going forward we shall be working with a Reporting Services system variable User!UserID and it is the value of this variable that will be passed to the stored procedure from the report body. This variable is the key component to ensuring that the pieces fit together and function correctly (see ADDENDA B). User!UserID contains the Domain and user ID of the individual requesting access to the data. Let us have a quick look at the contents of the security table. We note that there are two main users. User “ATRION\ssimon” is entitled to the Team 1 data and user “ATRION\SQLDB” is entitled to view only the Team2 data.

Constructing our stored procedures

Having created the necessary infrastructure, let us look at a small query which is going to return the required data to the appropriate teams. We see that (as is) the query returns all the data for Team1 as user “ATRION\ssimon” is permitted to see Team1 data. Changing the user to “ATRION\SQLDB” the following data is returned.

Restricting data columns

After a meeting with SQLShack Industries management, we find that there is additional data that must be locked down. Many SQLShack Industries reports contain a Total Sales per month field and management feels that Team1 should be able to view all corporate monthly sales, whilst the remaining teams may only view their own results. The following piece of code will help us achieve the desired results. Once again permissions are based upon the user ID detected upon entry into the Reporting Services / SharePoint Environment. 123456789101112131415161718192021 declare @UserID as Varchar(50)declare @WhatICanSee as varchar (50)set @UserID = 'ATRION\ssimon'set @WhatICanSee = (Select Min(team) from [dbo].[SQLShackSecurity] where UserID = rtrim(ltrim(@UserID))) if NOT @WhatICanSee is nullBeginselect YearMth,case when @WhatIcanSee <> 'Team1' then 0 else SUM (Team1_Revenue) end as Team1_Revenue, SUM (Team2_Revenue) as Team2_Revenue,case when @WhatIcanSee = 'Team1' then (SUM (Team1_Revenue) + SUM (Team2_Revenue)) else sum(Team2_Revenue) end as TTotalfrom(SELECT YearMth,case when name = 'Team1' then sales else 0 end as Team1_Revenue,case when name = 'Team2' then sales else 0 end as Team2_Revenue from [dbo].[YearlySales1])aGroup by YearMTH end A note of explanation is required for the following line of the code: 123 set @WhatICanSee = (Select Min(team) from [dbo].[SQLShackSecurity] where UserID = rtrim(ltrim(@UserID))) As we see in the table below, we may find the condition where a user has access to the data from more than one team. In this case, the rights are assigned based upon the rights allocated to the lowest team number (i.e. Team1). ATRION\ssimon Team1 GLOBAL RIGHTS ATRION\ssimon Team2 Team 2 ONLY Running our query for user ATRION\SQLDB we find that the figure for the Total Sales / Revenue are as follows: Changing the user to ATRION\ssimon we find the following results. The astute reader will note that in the case of user ATRION\SQLDB, he or she is only able to see the data for Team2 and the total column reflects that. User ATRION\ssimon, on the other hand is able to see all the data and therefore his or her total field reflects the summary total of sales for Team1 and Team2. We make one final change to this code and that is to add a new calculated field called “Monthee” which will contain the first three letters of the calendar month name (e.g. ‘Jan’). We utilize the RIGHT() function “RIGHT(YEARMTH,2)”. Note the usage of the RIGHT function to set the calendar month name (see above).

Data format conversion for matrix based reporting

Financial management at SQLShack Industries has also tasked us with showing these results in the form of a matrix. The thought behind this is, that it makes the results clearer to the decision maker. It should be remembered that the data format that we have just finished dealing with, is probably more conducive for a chart. This said, we are now going to structure a NEW stored procedure that will render the data in a format suitable for a matrix. We begin by adding twelve variables @Month01 through @Month12. By using the code at the top of the screen dump below, we are able to populate these twelve variables. The complete code listing may be found in ADDENDA A. The eagle–eyed reader will ask, why declare and populate twelve variable fields, when the year and month already exist within the “YearlySales1” database table. In approaching the extract in this manner, i.e. utilizing the twelve variables, we are certain of obtaining the current twelve month period (once again, please see the code in ADDENDA A). Remember that the table could contain data from a plethora of years. Adding the following pivot code to our original code (that we used for the chart), we now have a query that is more conducive to a matrix format. –– The values for @month01 through @month12 are calculated on the fly. The code to do so
–– may be found in the ADDENDA at the end of this article. 12345678910111213141516171819202122232425262728293031323334353637383940414243444546 set @sql = ' select name, [' + @month01+ '],[' + @month02+ '],[' +@month03+ '],[' +@month04+ '],[' +@month05 +'],[' + @month06+ '],[' +@month07+ '],[' +@month08+ '],[' +@month09+ '],[' +@month10+ '],[' + @month11+ '],[' +@month12 +'] from ' +' ( ' +' select Yearmth, name, value ' +' from #rawdata1 ' +' unpivot ' +' ( ' +' value for name in ([Team1_Revenue],[Team2_Revenue],[TTotal]) ' +' ) unpiv '+' ) src ' +' pivot ' +' ( ' +' sum(value) ' +' for YearMth in ([' + @month01+ '],[' + @month02+ '],[' +@month03+ '],[' +@month04+ '],[' +@month05 +'],[' + @month06+ '],[' +@month07+ '],[' +@month08+ '],[' +@month09+ '],[' +@month10+ '],[' + @month11+ '],[' +@month12 +'] )) piv ' + ‘order by name asc ' set @sql1 = @sql CREATE TABLE #rawdata55( [name] [varchar](75) NULL, [Month01] [decimal](10, 2) NULL, [Month02] [decimal](10, 2) NULL, [Month03] [decimal](10, 2) NULL, [Month04] [decimal](10, 2) NULL, [Month05] [decimal](10, 2) NULL, [Month06] [decimal](10, 2) NULL, [Month07] [decimal](10, 2) NULL, [Month08] [decimal](10, 2) NULL, [Month09] [decimal](10, 2) NULL, [Month10] [decimal](10, 2) NULL, [Month11] [decimal](10, 2) NULL, [Month12] [decimal](10, 2) NULL) --select @sqlinsert #rawdata55exec sp_executesql @SQL1 with recompile select * from #rawdata55END Now executing the query for user ATRION\ssimon we find: and for user ATRION\SQLDB we find: These are the results that we would have expected to obtain (see above).

Creating our first production reports

Opening SQL Server Data Tools, we create a new Reporting Services Project and name it “SQLShackReportingSecurity”. Should you be unfamiliar with Reporting Services or how to create a project, please do have a look at my earlier article entitled: “Now you see it, now you don’t” /now-see-now-dont/ Within this article I describe in great detail how to get started creating a Reporting Services project. We first create a shared “Data Source” (see below). This data source contains the necessary information to connect to the source data within the SQL Server database.

Creating our first report

Within our project we right click on the report folder, select “Add” and “New Item”. We add a new report as shown below: We click “Add” and we are returned to the report drawing surface. We are now going to create a vertical bar chart graph (see below). For this exercise we shall be utilizing a column chart (see above).

Creating our dataset

In order for us to access the raw data from the database table (i.e. the data which will be consumed by our bar chart), we must first create a dataset. Should you be unfamiliar with the process or not understand the concept of a “dataset”, then please do have a look at one of my earlier articles “Now you see it, now you don’t” /now-see-now-dont/ We click the “New” button (see above). The local data source dialog box is brought up (see below). We note above that we opt to use as “Shared Data Source”. This is the shared data source that we created at the start of the project. We click “OK” to leave the local data source dialog box and we are returned to the “DataSet Properties” box (see below). We opt for the “Stored Procedure” as the “Query type” and select “ServiceRevenue01” option as the procedure that we wish to utilize. We click OK to exit the “Dataset Properties” dialog box and we are returned to the report drawing surface (see below). Note our new dataset appears on the left hand side of the screen shot (see above). We now resize our chart control and assign the dataset (that we have just created) as the source of data for the chart (see below and to the right). We also add a title to the chart and call it “Revenue”. We set the charts series, values and category groups (See below). As we have done in past sessions together, we shall be using the “YearMth” field purely as a sorting field and use the “month names” column, “Monthee” as the ‘labels’ for the X axis. Note the way that we prevent the values of “YearMth” from appearing when the report is run (see below). Highlighting “YearMth” and selecting the “Category Group Properties” tab (see above) we bring up the “Category Group Properties” dialog box. We click the expression box for the “Label” option. The expression box opens. We replace the value “=Fields!Yearmth.Value” with “=Nothing” and Click OK,OK to exit the “Properties” box.

Configuring the necessary parameters

While the chart and the necessary data fields are now in place, we must now complete the necessary “wiring” and obtain the user’s login ID and pass that through to the stored procedure thus ensuring that the correct data is extracted and rendered. We define a Parameter called UserID (see below) Note that our parameter is going to be “Hidden”. On the “Available Values” tab, we leave the “Select from one of the following options:” radio button ‘as is’. Moving to the “Default Values” tab, we are going to set a default. We click on the “Specify values” radio button and click the “Add” and click the expressions box to open the “Expression” editor. The expressions box opens and we add “ =User!UserID” (see above). We click OK and OK to exit the “Report Parameter Properties” box. Moving to our dataset, we right click on the dataset name and open its properties dialog box. We click on the “Parameters” tab. Should our parameter @UserID not be there, then we must select the “Add” button to add the parameter @UserID (see above). Let us now run our report to see the results. The reader will note that I inserted a text box above the chart, to display the value of @UserID (see above). This obviously would NOT be there within the production environment and going forward, I have removed this text box from further screen shots.

Re-arranging the furniture

Prior to adding our matrix based report, we should really re-arrange the controls that we currently show upon our screen. I have taken the liberty of adding a text box above the chart and I have given my report the title “SQLShack Industries Team Revenue Report”. Further, I have labelled the Y axis as “Revenue” and set the property to currency (see above).

Adding a matrix to the mix

As you will remember, we created two store procedures. The second one was in the format that could be utilized with a matrix. We are now going to add that matrix to our report. We drag a “Matrix Report Item” onto the drawing surface. In a similar manner to which we created the chart dataset (above), we create an additional dataset for the matrix. The question that DOES arise is, “Could we have created one data set for both?” The answer is yes HOWEVER, I prefer to keep the processes as simple as possible as this gives you added flexibility to handle ‘change’. The screen shot above shows the dataset for the Matrix. Prior to configuring the matrix, we remove the “Column Grouping” as shown above (middle bottom). Further we are ONLY removing the Grouping and NOT the data (see above). Note that the left most column of the matrix is the “grouping“column. We are going to use the column “Name” (which contains the Team names) as the grouping field (see above). Further, we add eleven more columns to ensure that we have enough columns for the twelve months of the year. We are now going change the column headers to something more meaningful. We shall also right orient the revenue fields, in addition to adding fill to the matrices’ cells (see below). When we run our report for “ATRION\ssimon”, we find the following (see below). When we run our report for “ATRION\SQLDB”, we find the following (see below).

Conclusions

We have completed the work that SQLShack Industries’ management had requested. The data rendered within the reports reflected the data permissions that each group/team had. Whilst this technique is aimed for internal business consumption, it is far from the type of security that one would implement for users coming in through the firewall. As always, should you have any questions or concerns, please feel free to contact me. In the interim, Happy Programming!!

ADDENDA A

The code sample for the matrix may be seen below: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 /****** Script for SelectTopNRows command from SSMS ******/use [SQLShackFinancial]go--IF OBJECT_ID(N'tempdb..#rawdata1') IS NOT NULL--BEGIN-- DROP TABLE #rawdata1--END--IF OBJECT_ID(N'tempdb..#rawdata2') IS NOT NULL--BEGIN-- DROP TABLE #rawdata2--END--IF OBJECT_ID(N'tempdb..#rawdata3') IS NOT NULL--BEGIN-- DROP TABLE #rawdata3--END--IF OBJECT_ID(N'tempdb..#rawdata55') IS NOT NULL--BEGIN-- DROP TABLE #rawdata55--END--goAlter procedure SalesRevenue01Matrix(@UserID as Varchar(20))asdeclare @Yearr varchar(4)declare @LowYearr varchar(4)declare @SQL varchar(2000)declare @SQL1 nvarchar(2000)declare @decider intdeclare @month01 varchar(6)declare @month02 varchar(6)declare @month03 varchar(6)declare @month04 varchar(6)declare @month05 varchar(6)declare @month06 varchar(6)declare @month07 varchar(6)declare @month08 varchar(6)declare @month09 varchar(6)declare @month10 varchar(6)declare @month11 varchar(6)declare @month12 varchar(6)declare @beginFiscal datedeclare @endFiscal date--declare @YearIncoming as varchar(4)set @decider = datepart(Month,convert(date,getdate()))set @Yearr = datepart(YEAR,Convert(date,Getdate()))set @Lowyearr = @Yearr set @Lowyearr = case when @decider > 6 then datepart(YEAR,Convert(date,Getdate())) else @LowYearr endset @Yearr = case when @decider >= 7 then datepart(YEAR,Convert(date,Getdate())) + 1 else @Yearr +1 endset @Beginfiscal = convert(varchar(4),@LowYearr) + '0701'set @Endfiscal = convert(varchar(4),@Yearr) + '0630' set @month01 = convert(varchar(4),datepart(Year,@beginFiscal)) + case when len(convert(varchar(2),datepart(Month,@beginFiscal))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,@beginFiscal))) else convert(varchar(2),datepart(Month,@beginFiscal)) end set @month02 = convert(varchar(4),datepart(Year,@beginFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,1,@beginFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,1,@beginFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,1,@beginFiscal))) end set @month03 = convert(varchar(4),datepart(Year,@beginFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,2,@beginFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,2,@beginFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,2,@beginFiscal))) end set @month04 = convert(varchar(4),datepart(Year,@beginFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,3,@beginFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,3,@beginFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,3,@beginFiscal))) end set @month05 = convert(varchar(4),datepart(Year,@beginFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,4,@beginFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,4,@beginFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,4,@beginFiscal))) end set @month06 = convert(varchar(4),datepart(Year,@beginFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,5,@beginFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,5,@beginFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,5,@beginFiscal))) end set @month07 = convert(varchar(4),datepart(Year,@endFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,-5,@endFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,-5,@endFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,-5,@endFiscal))) end set @month08 = convert(varchar(4),datepart(Year,@endFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,-4,@endFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,-4,@endFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,-4,@endFiscal))) end set @month09 = convert(varchar(4),datepart(Year,@endFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,-3,@endFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,-3,@endFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,-3,@endFiscal))) end set @month10 = convert(varchar(4),datepart(Year,@endFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,-2,@endFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,-2,@endFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,-2,@endFiscal))) end set @month11 = convert(varchar(4),datepart(Year,@endFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,-1,@endFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm,-1,@endFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,-1,@endFiscal))) end set @month12 = convert(varchar(4),datepart(Year,@endFiscal)) + case when len(convert(varchar(2),datepart(Month,dateadd(mm,0,@endFiscal)))) = 1 then convert(varchar(2),'0' + convert(varchar(2),datepart(Month,dateadd(mm, 0,@endFiscal)))) else convert(varchar(2),datepart(Month,dateadd(mm,0,@endFiscal))) end -- select @Month01,@Month02,@Month03,@Month04,@Month05,@Month06 --select @Month07,@Month08,@Month09,@Month10,@Month11,@Month12 --declare @UserID as Varchar(50)declare @WhatICanSee as varchar (50)--set @UserID = 'ATRION\ssimon'Set @UserID = rtrim(ltrim(@UserID))set @WhatICanSee = (Select Min(team) from [dbo].[SQLShackSecurity] where UserID = rtrim(ltrim(@UserID))) --set @WhatICanSee='Team1'If Not @WhatICanSee is null BEGINselect YearMth,case when @WhatIcanSee <> 'Team1' then 0 else SUM (Team1_Revenue) end as Team1_Revenue, SUM (Team2_Revenue) as Team2_Revenue,case when @WhatIcanSee = 'Team1' then (SUM (Team1_Revenue) + SUM (Team2_Revenue)) else sum(Team2_Revenue) end as TTotal into #rawdata1 from(SELECT YearMth,case when name = 'Team1' then sales else 0 end as Team1_Revenue,case when name = 'Team2' then sales else 0 end as Team2_Revenue from [dbo].[YearlySales1])aGroup by YearMTH set @sql = ' select name, [' + @month01+ '],[' + @month02+ '],[' +@month03+ '],[' +@month04+ '],[' +@month05 +'],[' + @month06+ '],[' +@month07+ '],[' +@month08+ '],[' +@month09+ '],[' +@month10+ '],[' + @month11+ '],[' +@month12 +'] from ' +' ( ' +' select Yearmth, name, value ' +' from #rawdata1 ' +' unpivot ' +' ( ' +' value for name in ([Team1_Revenue],[Team2_Revenue],[TTotal]) ' +' ) unpiv '+' ) src ' +' pivot ' +' ( ' +' sum(value) ' +' for YearMth in ([' + @month01+ '],[' + @month02+ '],[' +@month03+ '],[' +@month04+ '],[' +@month05 +'],[' + @month06+ '],[' +@month07+ '],[' +@month08+ '],[' +@month09+ '],[' +@month10+ '],[' + @month11+ '],[' +@month12 +'] )) piv ' + ' order by name asc ' set @sql1 = @sql CREATE TABLE #rawdata55( [name] [varchar](75) NULL, [Month01] [decimal](10, 2) NULL, [Month02] [decimal](10, 2) NULL, [Month03] [decimal](10, 2) NULL, [Month04] [decimal](10, 2) NULL, [Month05] [decimal](10, 2) NULL, [Month06] [decimal](10, 2) NULL, [Month07] [decimal](10, 2) NULL, [Month08] [decimal](10, 2) NULL, [Month09] [decimal](10, 2) NULL, [Month10] [decimal](10, 2) NULL, [Month11] [decimal](10, 2) NULL, [Month12] [decimal](10, 2) NULL) insert #rawdata55exec sp_executesql @SQL1 with recompile select * from #rawdata55 END go

ADDENDA B

User ATRION\ssimon observes the following when a report is pushed to SharePoint User ATRION\SQLDB observes the following when a report is pushed to SharePoint Author Recent Posts Steve SimonSteve Simon is a SQL Server MVP and a senior BI Development Engineer with Atrion Networking. He has been involved with database design and analysis for over 29 years.

Steve has presented papers at 8 PASS Summits and one at PASS Europe 2009 and 2010. He has recently presented a Master Data Services presentation at the PASS Amsterdam Rally.

Steve has presented 5 papers at the Information Builders' Summits. He is a PASS regional mentor.

View all posts by Steve Simon Latest posts by Steve Simon (see all) Reporting in SQL Server – Using calculated Expressions within reports - December 19, 2016 How to use Expressions within SQL Server Reporting Services to create efficient reports - December 9, 2016 How to use SQL Server Data Quality Services to ensure the correct aggregation of data - November 9, 2016

Related posts

Using a cursor to correctly extract SQL Server data and place it in a Reporting Services matrix Reporting in SQL Server – create a chart based on the data extracted for a given date range Create reports like a champion! Tips and tricks with Reporting Services Which Reporting Services dataset fields are being utilized by the reports? SQL Server and BI – Creating a query for the revenue projection 1,011 Views

Follow us

Popular

SQL Convert Date functions and formats SQL Variables: Basics and usage SQL PARTITION BY Clause overview Different ways to SQL delete duplicate rows from a SQL Table How to UPDATE from a SELECT statement in SQL Server SQL Server functions for converting a String to a Date SELECT INTO TEMP TABLE statement in SQL Server SQL WHILE loop with simple examples How to backup and restore MySQL databases using the mysqldump command CASE statement in SQL Overview of SQL RANK functions Understanding the SQL MERGE statement INSERT INTO SELECT statement overview and examples SQL multiple joins for beginners with examples Understanding the SQL Decimal data type DELETE CASCADE and UPDATE CASCADE in SQL Server foreign key SQL Not Equal Operator introduction and examples SQL CROSS JOIN with examples The Table Variable in SQL Server SQL Server table hints – WITH (NOLOCK) best practices

Trending

SQL Server Transaction Log Backup, Truncate and Shrink Operations Six different methods to copy tables between databases in SQL Server How to implement error handling in SQL Server Working with the SQL Server command line (sqlcmd) Methods to avoid the SQL divide by zero error Query optimization techniques in SQL Server: tips and tricks How to create and configure a linked server in SQL Server Management Studio SQL replace: How to replace ASCII special characters in SQL Server How to identify slow running queries in SQL Server SQL varchar data type deep dive How to implement array-like functionality in SQL Server All about locking in SQL Server SQL Server stored procedures for beginners Database table partitioning in SQL Server How to drop temp tables in SQL Server How to determine free space and file size for SQL Server databases Using PowerShell to split a string into an array KILL SPID command in SQL Server How to install SQL Server Express edition SQL Union overview, usage and examples

Solutions

Read a SQL Server transaction logSQL Server database auditing techniquesHow to recover SQL Server data from accidental UPDATE and DELETE operationsHow to quickly search for SQL database data and objectsSynchronize SQL Server databases in different remote sourcesRecover SQL data from a dropped table without backupsHow to restore specific table(s) from a SQL Server database backupRecover deleted SQL data from transaction logsHow to recover SQL Server data from accidental updates without backupsAutomatically compare and synchronize SQL Server dataOpen LDF file and view LDF file contentQuickly convert SQL code to language-specific client codeHow to recover a single table from a SQL Server database backupRecover data lost due to a TRUNCATE operation without backupsHow to recover SQL Server data from accidental DELETE, TRUNCATE and DROP operationsReverting your SQL Server database back to a specific point in timeHow to create SSIS package documentationMigrate a SQL Server database to a newer version of SQL ServerHow to restore a SQL Server database backup to an older version of SQL Server

Categories and tips

►Auditing and compliance (50) Auditing (40) Data classification (1) Data masking (9) Azure (295) Azure Data Studio (46) Backup and restore (108) ▼Business Intelligence (482) Analysis Services (SSAS) (47) Biml (10) Data Mining (14) Data Quality Services (4) Data Tools (SSDT) (13) Data Warehouse (16) Excel (20) General (39) Integration Services (SSIS) (125) Master Data Services (6) OLAP cube (15) PowerBI (95) Reporting Services (SSRS) (67) Data science (21) ►Database design (233) Clustering (16) Common Table Expressions (CTE) (11) Concurrency (1) Constraints (8) Data types (11) FILESTREAM (22) General database design (104) Partitioning (13) Relationships and dependencies (12) Temporal tables (12) Views (16) ►Database development (418) Comparison (4) Continuous delivery (CD) (5) Continuous integration (CI) (11) Development (146) Functions (106) Hyper-V (1) Search (10) Source Control (15) SQL unit testing (23) Stored procedures (34) String Concatenation (2) Synonyms (1) Team Explorer (2) Testing (35) Visual Studio (14) DBAtools (35) DevOps (23) DevSecOps (2) Documentation (22) ETL (76) ►Features (213) Adaptive query processing (11) Bulk insert (16) Database mail (10) DBCC (7) Experimentation Assistant (DEA) (3) High Availability (36) Query store (10) Replication (40) Transaction log (59) Transparent Data Encryption (TDE) (21) Importing, exporting (51) Installation, setup and configuration (121) Jobs (42) ►Languages and coding (686) Cursors (9) DDL (9) DML (6) JSON (17) PowerShell (77) Python (37) R (16) SQL commands (196) SQLCMD (7) String functions (21) T-SQL (275) XML (15) Lists (12) Machine learning (37) Maintenance (99) Migration (50) Miscellaneous (1) ►Performance tuning (869) Alerting (8) Always On Availability Groups (82) Buffer Pool Extension (BPE) (9) Columnstore index (9) Deadlocks (16) Execution plans (125) In-Memory OLTP (22) Indexes (79) Latches (5) Locking (10) Monitoring (100) Performance (196) Performance counters (28) Performance Testing (9) Query analysis (121) Reports (20) SSAS monitoring (3) SSIS monitoring (10) SSRS monitoring (4) Wait types (11) ►Professional development (68) Professional development (27) Project management (9) SQL interview questions (32) Recovery (33) Security (84) Server management (24) SQL Azure (271) SQL Server Management Studio (SSMS) (90) SQL Server on Linux (21) ►SQL Server versions (177) SQL Server 2012 (6) SQL Server 2016 (63) SQL Server 2017 (49) SQL Server 2019 (57) SQL Server 2022 (2) ►Technologies (334) AWS (45) AWS RDS (56) Azure Cosmos DB (28) Containers (12) Docker (9) Graph database (13) Kerberos (2) Kubernetes (1) Linux (44) LocalDB (2) MySQL (49) Oracle (10) PolyBase (10) PostgreSQL (36) SharePoint (4) Ubuntu (13) Uncategorized (4) Utilities (21) Helpers and best practices BI performance counters SQL code smells rules SQL Server wait types © 2022 Quest Software Inc. ALL RIGHTS RESERVED. GDPR Terms of Use Privacy
Share:
0 comments

Comments (0)

Leave a Comment

Minimum 10 characters required

* All fields are required. Comments are moderated before appearing.

No comments yet. Be the first to comment!