Brett Kaiser has posted a article called "How do I track data changes in a database" including his real usefull coding about his idea of doing this via T-SQL automatically every time a DELETE or UPDATE Modification will be executed.
The following content is intellectual property of Brett Kaiser, the original posting can be found here:
USE Northwind SET NOCOUNT ON GO
-- For example purposes, create a sample tables CREATE TABLE myTable99(Col1 int IDENTITY(1,1), Col2 char(1), Col3 datetime DEFAULT(GetDate()), Col4 decimal(5,2)) CREATE TABLE x002548.myTable99(Col1 int IDENTITY(1,1), Col2 char(1), Col3 datetime DEFAULT(GetDate()), Col4 decimal(5,2)) GO
-- Give the sample tables some data INSERT INTO myTable99(Col2, Col4) SELECT 'x', 1 UNION ALL SELECT 'y', 2 UNION ALL SELECT 'z', 3 INSERT INTO x002548.myTable99(Col2, Col4) SELECT 'a', 24 UNION ALL SELECT 'b', 25 UNION ALL SELECT 'c', 26
--Lets have a look SELECT 'x002548' AS Source, * FROM x002548.myTable99 UNION ALL SELECT 'dbo' AS Source, * FROM myTable99 GO
-- CREATE A Driver Table for all Tables in your catalog you wish to audit CREATE TABLE myAudit99(TABLE_CATALOG sysname, TABLE_SCHEMA sysname, TABLE_NAME sysname) GO
-- Populate the audit driver table with the table you want...you can use any type of process for this INSERT INTO myAudit99(TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME) SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.Tables WHERE TABLE_NAME LIKE 'myTable99%'
-- Lets create some audit tables based on the Driver
DECLARE myCursor99 CURSOR FOR SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME FROM myAudit99
DECLARE @TABLE_CATALOG sysname, @TABLE_SCHEMA sysname, @TABLE_NAME sysname, @COLUMN_NAMES varchar(8000), @sql varchar(8000) SELECT @COLUMN_NAMES = '' OPEN myCursor99
FETCH NEXT FROM myCursor99 INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME
WHILE @@FETCH_STATUS = 0 BEGIN SELECT @SQL = 'CREATE TABLE ' + @TABLE_CATALOG + '.' + @TABLE_SCHEMA + '.' + @TABLE_NAME + '_H (' + ' HIST_ADD_DT datetime DEFAULT (getDate()), HIST_ADD_TYPE char(1) NOT NULL' + ', HIST_ADD_SYSTEM_USER sysname NOT NULL, HIST_ADD_USER_NAME sysname NOT NULL' + ', HIST_ADD_HOSTNAME sysname NOT NULL, HIST_ADD_SPID int NOT NULL, HIST_ADD_DESC varchar(50) ' , @COLUMN_NAMES = @COLUMN_NAMES + ', ' + COLUMN_NAME + ' ' + DATA_TYPE + CASE WHEN CHARACTER_MAXIMUM_LENGTH IS NOT NULL THEN '(' + CONVERT(varchar(20),CHARACTER_MAXIMUM_LENGTH) + ')' WHEN DATA_TYPE = 'decimal' THEN '(' + CONVERT(varchar(20),NUMERIC_PRECISION) + ',' + CONVERT(varchar(20),NUMERIC_SCALE) + ')' ELSE '' END FROM INFORMATION_SCHEMA.Columns WHERE TABLE_CATALOG = @TABLE_CATALOG AND TABLE_SCHEMA = @TABLE_SCHEMA AND TABLE_NAME = @TABLE_NAME ORDER BY ORDINAL_POSITION
SELECT @SQL = @SQL + @COLUMN_NAMES + ')'
EXEC(@SQL)
SELECT @SQL = '', @COLUMN_NAMES = ''
FETCH NEXT FROM myCursor99 INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME
END
CLOSE myCursor99 DEALLOCATE myCursor99 GO
SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME Like 'myTable99%' ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION
-- Now Lets create the audit TRIGGERS
DECLARE myCursor99 CURSOR FOR SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME FROM myAudit99
DECLARE @TABLE_CATALOG sysname, @TABLE_SCHEMA sysname, @TABLE_NAME sysname, @COLUMN_NAMES varchar(8000), @sql varchar(8000) SELECT @COLUMN_NAMES = '' OPEN myCursor99
FETCH NEXT FROM myCursor99 INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME
WHILE @@FETCH_STATUS = 0 BEGIN SELECT @COLUMN_NAMES = @COLUMN_NAMES + ', ' + COLUMN_NAME FROM INFORMATION_SCHEMA.Columns WHERE TABLE_CATALOG = @TABLE_CATALOG AND TABLE_SCHEMA = @TABLE_SCHEMA AND TABLE_NAME = @TABLE_NAME ORDER BY ORDINAL_POSITION
SELECT @SQL = 'CREATE TRIGGER ' + @TABLE_SCHEMA + '_' + @TABLE_NAME + '_TR ON ' + @TABLE_SCHEMA + '.' +@TABLE_NAME + ' FOR UPDATE, DELETE AS ' + ' DECLARE @HOSTNAME sysname, @DESC varchar(50) ' + ' SELECT @HOSTNAME = hostname from master.dbo.sysprocesses where spid = @@SPID ' + ' IF EXISTS(SELECT * FROM ' + @TABLE_NAME + ') SELECT @DESC = ' + '''' + '''' + ' ELSE SELECT @DESC = ' + '''' + 'MASS DELETE' + '''' + ' If Exists (Select * From Inserted) And Exists (Select * From Deleted) ' + ' INSERT INTO ' + @TABLE_NAME + '_H ( ' + ' HIST_ADD_TYPE, HIST_ADD_SYSTEM_USER, HIST_ADD_USER_NAME, HIST_ADD_HOSTNAME, HIST_ADD_SPID, HIST_ADD_DESC' + @COLUMN_NAMES + ')' + ' SELECT ''U'', SYSTEM_USER, USER_NAME(), @HOSTNAME, @@SPID, @DESC' + @COLUMN_NAMES + ' FROM deleted' + ' If Not Exists (Select * From Inserted) And Exists (Select * From Deleted) And @DESC = '''' ' + ' INSERT INTO ' + @TABLE_NAME + '_H ( ' + ' HIST_ADD_TYPE, HIST_ADD_SYSTEM_USER, HIST_ADD_USER_NAME, HIST_ADD_HOSTNAME, HIST_ADD_SPID, HIST_ADD_DESC' + @COLUMN_NAMES + ')' + ' SELECT ''D'', SYSTEM_USER, USER_NAME(), @HOSTNAME, @@SPID, @DESC' + @COLUMN_NAMES + ' FROM deleted' + ' If Not Exists (Select * From Inserted) And Exists (Select * From Deleted) And @DESC <> '''' ' + ' INSERT INTO ' + @TABLE_NAME + '_H ( ' + ' HIST_ADD_TYPE, HIST_ADD_SYSTEM_USER, HIST_ADD_USER_NAME, HIST_ADD_HOSTNAME, HIST_ADD_SPID, HIST_ADD_DESC' + @COLUMN_NAMES + ')' + ' SELECT TOP 1 ''D'', SYSTEM_USER, USER_NAME(), @HOSTNAME, @@SPID, @DESC' + @COLUMN_NAMES + ' FROM deleted'
EXEC(@SQL)
SELECT @SQL = '', @COLUMN_NAMES = ''
FETCH NEXT FROM myCursor99 INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME
END
CLOSE myCursor99 DEALLOCATE myCursor99 GO
-- Now let's pretend to be an ignorant boss...not to much of a stretch there....
UPDATE myTable99 SET Col2 = 'G'
SELECT * FROM myTable99_H
DELETE FROM myTable99 WHERE Col1 = 1
SELECT * FROM myTable99_H
DELETE FROM x002548.myTable99
SELECT * FROM x002548.myTable99_H
SELECT * FROM myTable99
SELECT * FROM x002548.myTable99 GO
SET NOCOUNT OFF DROP TABLE myAudit99 DROP TRIGGER dbo_myTable99_TR DROP TRIGGER x002548_myTable99_TR DROP TABLE dbo.myTable99 DROP TABLE x002548.myTable99 DROP TABLE dbo.myTable99_H DROP TABLE x002548.myTable99_H GO
Grant Robinson has developed an interesting online-game, which can be found via the project site.
All you have to do is to launch the project and guess the search term which could have brought up the pictures shown on the screen.
Nice game - if you like it too think about donating...
Randy Dyess has published an article called "Auditing Your SQL Server Environment: Part II (Reviewing Role Memberships)"
The following content is intellectual property of Randy Dyess, the original posting can be found here:
"Roles should be in foremost in your mind when planning the security of your SQL Server environments. Auditing inherited SQL Server installations is a relatively easy thing to accomplish, and all DBAs should audit their environment and create documentation if they have not already done so. Once you can document the logins assigned to each of your fixed and user-defined roles, you can start to remove any duplication of permissions which can reduce the time needed to troubleshoot future permission errors."
--Use the master database USE master go
IF OBJECT_ID('dbo.spRoleMembers') IS NOT NULL DROP PROCEDURE dbo.spRoleMembers GO
CREATE PROCEDURE dbo.spRoleMembers AS /************************************************************ Creation Date: 04/28/02 Created By: Randy Dyess Web Site: www.TransactSQL.Com Email: RandyDyess@TransactSQL.Com Purpose: Loops through all databases and obtains member for database roles as well as server role members. Location: master database Output Parameters: None Return Status: None Called By: None Calls: None Data Modifications: None Updates: None
************************************************************/ SET NOCOUNT ON
--Variables DECLARE @lngCounter INTEGER DECLARE @strDBName VARCHAR(50) DECLARE @strSQL NVARCHAR(4000)
--Temp table to hold database and user-define role user names CREATE TABLE #tRolemember ( strServerName VARCHAR(50) DEFAULT @@SERVERNAME ,strDBName VARCHAR(50) ,strRoleName VARCHAR(50) ,strUserName VARCHAR(50) ,strUserID VARCHAR(100) )
--Temp table to hold database names CREATE TABLE #tDBNames (lngID INTEGER IDENTITY(1,1) ,strDBName VARCHAR(50) )
--Create permanent table IF OBJECT_ID ('dbo.tRolemember') IS NULL BEGIN CREATE TABLE dbo.tRolemember ( strServerName VARCHAR(50) ,strDBName VARCHAR(50) ,strRoleName VARCHAR(50) ,strUserName VARCHAR(50) ,strUserID VARCHAR(100) ) END
--Obtain members of each server role INSERT INTO #tRolemember (strRoleName, strUserName, strUserID) EXEC dbo.sp_helpsrvrolemember
--Obtain database names INSERT INTO #tDBNames (strDBName) SELECT name FROM master.dbo.sysdatabases SET @lngCounter = @@ROWCOUNT
--Loop through databases to obtain members of database roles and user-defined roles WHILE @lngCounter > 0 BEGIN
--Get database name from temp table SET @strDBName = (SELECT strDBName FROM #tDBNames WHERE lngID = @lngCounter)
--Obtain members of each database and user-defined role SET @strSQL = 'INSERT INTO #tRolemember (strRoleName, strUserName, strUserID) EXEC ' + @strDBName + '.dbo.sp_helprolemember'
EXEC sp_executesql @strSQL
--Update database name in temp table UPDATE #tRolemember SET strDBName = @strDBName WHERE strDBName IS NULL
SET @lngCounter = @lngCounter - 1
END
--Place data into permanent table INSERT INTO tRolemember SELECT trm.* FROM #tRolemember trm LEFT JOIN tRoleMember prm ON trm.strUserName = prm.strUserName AND trm.strDBName = prm.strDBName AND trm.strRoleName = prm.strRoleName AND trm.strServerName = prm.strServerName WHERE prm.strServerName IS NULL
GO
--Test Stored Procedure EXEC dbo.spRoleMembers
PRINT 'Display by User' SELECT strUserName, strDBName, strRoleName, strServerName FROM tRolemember WHERE strUserName <> 'dbo' ORDER BY strUserName
PRINT 'Display by Role' SELECT strRoleName, strDBName, strUserName,strServerName FROM tRolemember WHERE strUserName <> 'dbo' ORDER BY strRoleName
PRINT 'Display by Database' SELECT strDBName, strRoleName,strUserName, strServerName FROM tRolemember WHERE strUserName <> 'dbo' ORDER BY strDBName
Randy also has published a script about auditing user's passwords
The following content is intellectual property of Randy Dyess, the original posting can be found here:
IF OBJECT_ID('dbo.spAuditPasswords') IS NOT NULL DROP PROCEDURE dbo.spAuditPasswords GO
CREATE PROCEDURE dbo.spAuditPasswords AS /**************************************************************************** Creation Date: 03/22/02 Created By: Randy Dyess Web Site: www.TransactSQL.Com Email: RandyDyess@TransactSQL.Com Purpose: Perform a simple audit of user's passwords Location: master database Output Parameters: None Return Status: None Called By: None Calls: None Data Modifications: None Updates: None Date Author Purpose ---------- -------------------------- --------------------------------- ****************************************************************************/ SET NOCOUNT ON
--Variables DECLARE @lngCounter INTEGER DECLARE @lngCounter1 INTEGER DECLARE @lngLogCount INTEGER DECLARE @strName VARCHAR(256)
--Create table to hold SQL logins CREATE TABLE #tLogins ( numID INTEGER IDENTITY(1,1) ,strLogin SYSNAME NULL ,lngPass INTEGER NULL )
--Insert non ntuser into temp table INSERT INTO #tLogins (strLogin) SELECT name FROM master.dbo.syslogins WHERE isntname = 0 SET @lngLogCount = @@ROWCOUNT
--Determine if password is null and user iis SQL Login PRINT 'The following logins have blank passwords' SELECT name AS 'Login Name' FROM master.dbo.syslogins WHERE password IS NULL AND isntname = 0
--Determine if password and name are the ssame SET @lngCounter = @lngLogCount
WHILE @lngCounter <> 0 BEGIN SET @strName = (SELECT strLogin FROM #tLogins WHERE numID = @lngCounter)
UPDATE #tLogins SET lngPass = (SELECT PWDCOMPARE (@strName,(SELECT password FROM master.dbo.syslogins WHERE name = @strName))) WHERE numID = @lngCounter
SET @lngCounter = @lngCounter - 1 END
PRINT 'The following logins have passwords the same as their login name' SELECT strLogin AS 'Login Name' FROM #tLogins WHERE lngPass = 1
--Reset column for next password test UPDATE #tLogins SET lngPass = 0
--Determine if password is only one characcter long SET @lngCounter = @lngLogCount
WHILE @lngCounter <> 0 BEGIN SET @lngCounter1 = 1 SET @strName = (SELECT strLogin FROM #tLogins WHERE numID = @lngCounter) WHILE @lngCounter1 < 256 BEGIN UPDATE #tLogins SET lngPass = (SELECT PWDCOMPARE (CHAR(@lngCounter1),(SELECT password FROM master.dbo.syslogins WHERE name = @strName))) WHERE numID = @lngCounter AND lngPass <> 1 SET @lngCounter1 = @lngCounter1 + 1 END
SET @lngCounter = @lngCounter - 1 END
PRINT 'The following logins have one character passwords' SELECT strLogin AS 'Login Name' FROM #tLogins WHERE lngPass = 1 GO
--Test EXEC dbo.spAuditPasswords
And last but not least Bradley Morris has published an article about "How to Script User and Role Object Permissions in SQL Server"
You probably know that PASS Germany publishes a really sophisticated newsletter every month containing a load of useful informations regarding every topic of the SQL Server.
Because of being the German chapter they are all in German of course... 
You want to find this newsletter regularly in your In-box every first day of the month? Then go and join up and be a member of the German community!
After ruining my SDA I had to decide which toy to buy next...
The new mobile should meet the following requirements:
- synchronize contacts and calender items with my exchange in the way I like
[I think it is really boring if you have to use your Outlook in the way your mobile manufacturer thinks you should use it...]
- several profiles for several situations
- email ability
- qwertz-keyboard
- no pen for navigation
- long lasting accu
I do not need multiple ring tones, a camera, video, MP3 and so on - I have had that on the SDA and I used it only a couple of times...
I decided to buy a Blackberry 8707v, which is a german derivate of this one.
And you probably ask yourself why, especially because of Exchange 2003 bringing up "Exchange Direct Push" in SP2 and the Blackberry solution requiring additional installs and licenses and a seperate fee for the Blackberry service?
Mainly because of Christoph Stotz, being the chairman of the board of PASS Germany, teasing me due to my mail access and some problems in the first days... Christoph, you will have to answer me some more questions in the future I think... 
As pointed out by Volker Weber in his article the new solution is not a kind of real push-mail... And RIM now offers BlackBerry Enterprise Server™ Express which is a free solution if you do not need to have more than 15 users. (probably to tighten the sales regarding products and services, but hey, thats marketing! and a kind of Microsoft style also...)
So I decided that other users should make experiences using Exchange 2003 SP2 or Exchange 2007 and I will decide to jump onboard if I get aware of positive experiences in a year or two... If the Blackberry will live longer than the SDA... 
If you are engaged in the SQL Server community and techniques you probably know Joe Webb as a source of inspiration regarding SQL Server Notification Services [SQLNS].
But Joe does not have only write technical books about SQLNS, he also has written a guidebook for being self-employed called the The Rational Guide to IT Consulting which is pretty usefull and a kind of "Project REAL for self-employed consultants".
If you are interested in the post-installation steps required after you successfully have installed SAP BW 3.5 you should have a look at this document of the MyITgroup. They are also offering more interesting documents on other SAP BW topics.
If you have do deal with licensing issues after installing and post-installing I would suggest SAP License (BC-CST-SL) which contains step-by-step descriptions about doing license management via the transaction SLICENSE or via the OS level. Just as a remark: the OS level is usefull if you have forgotten that your license keys will expire, because it is the only chance to connetc to the system while the GUI is not working anymore...
And if you are interested in general informations about SAP licensing you should use this link to the SAP library.
Mark Miller has shared his experiences on competing against a SAP solution offering in his article SAP the New BI Player .
It seems that I am not the only one who expects that SAP is going to push the Business Warehouse within a short time to engage a new target group - even though they are bundling a bunch of components to SAP Netweaver (including BI, Enterprise Portal and some other interesting applications)... Sure there are enough SAP core customers which are not using BW at the moment to engage, but MS also is entering the market of SAP core customers with tools and techniques like SQL Server Reporting Services, Biztalk, Performance Point Server and so on. We will have to wait and see...
Mark also mentions the concept of BI Accelerator for high performance analytics and there we both also have the very same opinion:
"They also have the BI Accelerator for high performance analytics (i.e. hardware and extra license fees) to make your large queries respond quickly. Not a one running in Australia yet. My perception is that this is a mistake in product marketing for SAP. It makes it sound like if you have lot of data, you're going have performance problems so you need to invest in additional hardware and we are going charge you an additional license because the one you already bought doesn’t do the job. SAP needs to rethink this."
Sounds very weird, doesn´t it? 
Nobody should say that Microsoft and the product teams do not listen to feedback and are not willing to learn...
With SP 1 Microsoft had "killed" the "Select All" Parameter for Multivalue Parameters and thereby triggered many discussions throughout Reporting Services users like this one in Nick Barclay's BI Blog. There was a workaround provided but this means that many manual work had to be done after SP1 surprisingly suppressed the option "Select All"...
Brian Welcker now has given some explanations and announced that "Select All" Parameter for Multivalue Parameters will be reimplemented in SP2 and if you would like to get it earlier as SP2 arrives you could get in contact with Support Services and refer tor Knowledge Base Article #919478 - which is not published at the moment.
SSRS Team 0 : 1 SSRS Users I think this will be continued...

The following content is intellectual property of Brian Keller, the original posting can be found here.
"Report Manager is a solid, Web-based administrative tool for Reporting Services, but it is not the end-all-be-all of administrative functionality for a report server. There are many capabilities available through the Web service that Report Manager does not take advantage of. Case in point: Setting a security policy (otherwise known as a role assignment) for an item using Report Manager is a bit cumbersome, especially if the item for which you want to add a policy is nested several folders deep in your report server namespace. Let's take an example. Let's say you have a folder at “/Budgets/Finance” and you would like to give Bob permission to view reports in the Finance folder. You add a new role assignment for Bob and make him a Browser user of the Finance folder. Bob logs into Report Manager hoping to navigate to the Finance folder, but...Bob is not able to see any folders when he logs in. What gives? Well, unfortunately the path to Bob's Finance folder actually contains three items: The Home or root folder (”/”), the Budgets folder and the Finance folder. Because Bob is not allowed to view the root folder or the Budgets folder, he will never see the Finance folder for which he has permissions. Sorry Bob. In order to give Bob Browser permissions on the Finance folder, you must add Bob as a Browser of both the Home and Budgets folders. If you need to add more groups or users to the Finance folder, it can get downright tiresome. Oh, did I mention that every time you add a policy for Bob to one of the folders, the inherited policy is broken. Yes, that means that any users that enjoyed inherited permissions to those items (for example BUILTIN\Administrators or some other administrator group) no longer have any access rights. You will have to re-add inherited permissions as local policies on each of the three folders in our example. Yikes. Fortunately for Bob, Reporting Services offers rs.exe, a scripting utility with complete access to the Reporting Services Web service. You can use this scripting tool to automate certain tasks and to perform administrative functions that may not be easily automated through Report Manager.
The following sample script can be used to add a security policy for a nested folder or report which automatically gives the user permissions up the namespace tree. After using this script, the item is immediately accessible to the user. In addition, you can use this script to keep or delete the current set of policies for the item, including inherited ones. I haven't given the script the whole battery of tests yet, so if you play around with the code, try it on your test server only. If you find any problems or issues, let me know."
'=====================================================================
' File: AddItemSecurity.rss ' Summary: Demonstrates a script that can be used with RS.exe to ' set security on an item in Reporting Services. '---------------------------------------------------------------------
' THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY ' KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ' IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A ' PARTICULAR PURPOSE.
'=====================================================================*/
' ' Variables that are passed on the command line with the -v switch: ' userName - the name of the user for which to add a policy ' roleName - the name of the role to apply for the user (i.e. Browser, Content Manager) ' itemPath - the path of the item for which you want to add the policy (i.e. /SampleReports) ' keepCurrentPolicy - whether to keep the current policy and add the new one ' ' Sample command line: ' rs -i AddItemSecurity.rss -s http://localhost/reportserver -v userName="MyTestUser" ' -v roleName="Browser" -v itemPath="/SampleReports" -v keepCurrentPolicy="True"
Public Sub Main()
Dim isRoot As Boolean = False Dim inheritParent As Boolean Dim policies() As Policy Dim newPolicies() As Policy Dim policy As New Policy() Dim roles(0) As Role
roles(0) = New Role()
roles(0).Name = roleName
policy.Roles = roles
policy.GroupUserName = userName
While Not isRoot ' Once the root of the catalog is reached, ' stop applying policies
If itemPath = "/" Then isRoot = True End If
policies = rs.GetPolicies(itemPath, inheritParent)
' If the user selects not to keep inherited or current policy, ' empty the policy
If Not keepCurrentPolicy = "True" Then policies = Nothing End If
newPolicies = AddNewPolicy(policy, policies)
rs.SetPolicies(itemPath, newPolicies)
itemPath = GetParentPath(itemPath)
End While
Console.WriteLine("Policy successfully set.")
End Sub 'Main
' Method to parse the path of an item and retrieve ' the parent path of an item
Private Function GetParentPath(currentPath As String) As String
Dim delimiter As String = "/" Dim rx As New System.Text.RegularExpressions.Regex(delimiter) Dim childPath As String() = rx.Split(currentPath) Dim parentLength As Integer = childPath.Length - 1 Dim parentPath(parentLength) As String Dim i As Integer
For i = 0 To parentLength - 1 parentPath(i) = childPath(i) Next i
If parentPath.Length = 1 Then Return "/" Else Return String.Join("/", parentPath) End If
End Function 'GetParentPath
' Takes the policy to add and applies it to the current set ' of policies if applicable
Private Function AddNewPolicy(policyToAdd As Policy, policies() As Policy) As Policy() If Not (policies Is Nothing) Then Dim policy As Policy For Each policy In policies If policy.GroupUserName = policyToAdd.GroupUserName Then Throw New Exception("The supplied User policy already exists for the item.") End If Next policy
Dim list As New System.Collections.ArrayList(policies) list.Add(policyToAdd) Return CType(list.ToArray(GetType(Policy)), Policy()) Else policies = New Policy(0) {} policies(0) = policyToAdd Return policies End If
End Function 'AddNewPolicy
The following content is intellectual property of Brian Keller, the original posting can be found here.
"I presented some demos at this year's PASS (Professional Association of SQL Server) Community Summit on how to use the rskeymgmt utility in Reporting Services. This is a crucial tool and should be used after every Reporting Services installation. What is it good for? Well, it can do several things, least of which is to extract and store the symmetric keys used to encrypt data in the report server database or catalog. This tool captures the complete key set that is defined during setup, and stores it as a file that you can save to disk or to removable storage media. You will absolutely need this key at some point if the account that is used for the ReportServer Windows service changes in some way (if a password is changed for instance) or if you want to connect a new report server to an existing report server database instance. Without the ability to apply this key at a later date to a report server instance, you may be forced to delete all encrypted data in your catalog including data source and user information. The rskeymgmt utility can help with that as well, but this shouldn't be necessary as long as you back up the key. The key is an integral part of storing encrypted data. If, at some point, the encryption key for the report server instance is different from the key used to store encrypted content in the database (i.e. a new report server installation, but an existing catalog), you report server will not function properly. So, bottom line, store your encryption key on a floppy disk for safe keeping using rskeymgmt. You can read the specifics about the tool on MSDN here"
Identifying the User during runtime sometimes can be usefull for your report header or footer, can be used to filter data or for parameters, and so on but it bars users from subscribing to reports, because Reporting Services is not able to identify the user from the subscription.
Brian Cooper had published a workaround for the known issue coming around using User!UserID in Reporting Services, but the content is gone...I discovered that during a discussion at the MSDN forum about the problem with User!UserID in datadriven subscriptions.
Jan Pieter Posthuma remembered the code and had the correct hint to solve this problem - many thanks!
Declare that parameter with a default value of the output of the custom code function (Code.UserName()) and thru out the report you use this parameter as replacement for the User!UserID. When scheduling this report you bind this parameter with the output from your subscription query.
In case you haven't got the custom code from the weblog:
Public Function UserName() Try Return Report.User!UserID Catch Return "System" End Try End Function
I have discovered, that several links I have had in my archive and also in this blog are currently not working anymore, because:
- content has moved or is no longer available
- blog was moved to another blogging software without migrating the content
If you would like to have an example: http://brianecooper.com/coop/archive/2005/03/15/270.aspx Brian has changed the blogging software and has not moved all posts yet. I really would have needed the workaround he provided in his post urgently, but I only had stored the link and not the content...
Though some of my links aren´t working and useful content is not available anymore. Therefor I decided not just to link content in the future but also to copy the content - including a reference to the original author and original source of course! - to my blog to assure availability.
Today a customer of mine remarked, that using the URL Access to show a report in an application without using the report manager does not refresh in a proper way if you use rc:Toolbar=false to hide the toolbar and leads to a non-refreshed report showing "old" values while displaying the toolbar shows a refreshed report
It seems, that activating the toolbar opens up a new session every time the report is opened whereas hiding the toolbar upholds the session and for that purpose the content is not re-rendered. If you want to get rid of this behavior you can use rs:ClearSession=true to force re-rendering and remove all report instances associated with an authenticated user from session.
Therefor the correct URL Access Syntax to access a report in HTML mode without a toolbar and with actual data will be something like: http://servername/reportserver?/folder/report name&rs:Command=Render&rs:format=HTML4.0&rc:Toolbar=false&rs:ClearSession=true
|