DACPAC SQL Server dropping schema permissions - sql-server

I am trying to use a DACPAC database project in Azure Data Studio.
So far, it works fine except for the "publishing" of the project to the actual DB.
When I generate the delta script, I see that all permissions on all schemas are being dropped.
I know that I could exclude certain objects:
SQL Server DACPAC Deployment Dropping Users/Roles/Permissions
However, I would prefer to have also the permissions of DB roles on a schema in the DB project.
Here, of course, the order is important. (Create schema, create user, create DB role, add user to DB role, grant permission for DB role on schema)
How (and to which file) can I add the schema permissions to the project and how can it be ensured that the TSQL statements that are generated are executed in the correct oder?
Thx.

At the linked QA have a look at the XML: there are separate parameters
DropPermissionsNotInSource
DropRoleMembersNotInSource
represented in sqlproj/publish.xml in a reversed way
<DoNotDropRoleMembership>True</DoNotDropRoleMembership>
<DoNotDropPermissions>True</DoNotDropPermissions>
By switching them to "do not drop" state you can avoid excluding permissions from deployment. Thus new permissions (defined in project but missing on target server) would be created but old ones (existing on target server but missing in the project) will not be dropped. Same goes for role membership.
Valid command order in publish script is guaranteed by the SSDT engine.
Still, permissions on target server can be lost if publishing requires object recreation. For example if you alter table-type then referencing procs will be dropped and recreated after type recreation.

Related

SSDT - specify authorization user on schema create

I have a sqlproj XML for Azure SQL Database. I want to deploy database with several tables into specific schema which is also created using this build. How to specify what user should be used for CREATE SCHEMA [schema-name] AUTHORIZATION [user] ? By default it uses user dbo but I need to change it. How to specify it in the sqlproj?
Sounds like you are looking in a wrong place. All database schema definitions in SSDT, by default, are placed into the Security folder. In it, you will have your schema-name.sql file, and there you can adjust the authorization clause.
For the project to build, the owner of that schema should also be present in the project. Most likely, you will find it in the same folder.
It appeared the user (service principal) trying to deploy the solution to SQL Database was not set as an AAD admin on the SQL server. It seems a little bit strange to me, but it worked.

SQL Server project - how to publish stored procedure permissions

In my .NET WinForms application (in a Visual Studio solution), I have the tables and stored procedures in a SQL Server project within the solution so I can easily keep my schema under version control, and I can successfully use the 'Publish' feature to deploy schema changes to the development database.
I'm getting ready to deploy my application and have asked a user to trial the application on their PC against the development database prior to rolling out the new application and database schema changes to production company wide.
What I'm finding is that the application is throwing SqlException. I've managed to track this down to permissions on the new stored procedures (obviously, I don't have this issue as the owner of the stored procedures).
I can manually correct this by granting permissions on the stored procedure(s), as follows
GRANT EXECUTE ON [dbo].[<tablename(s)>] TO DatabaseUsers
...but what I'd ideally like to do is include this within the definition of the stored procedure(s) in the SQL Server project that's under version control.
I've tried adding the above statement to the end of the stored procedure definition (below) in the SQL Server project, the output from the deployment script seems to show the command being executed, however whilst it updates the stored procedure, it won't touch the permissions.
-- Snipped 50 lines above for brevity
OR c.name LIKE #search
OR CAST(it.id AS VARCHAR) LIKE #search
OR ig.name LIKE #search
ORDER BY it.id
END
GRANT EXECUTE ON [dbo].[search_items_allfields] TO DatabaseUsers
GO
I've also tried adding an additional GO before the GRANT statement in the above definition, but then I'm unable to use the publish script, as it refuses to run due to not being able to resolve the group 'DatabaseUsers' (without the GO, it's still unable to resolve it, but is happy enough to run it).
In addition to the GO before the GRANT (so it's not part of the procedure), you need to add a script for the role to your project to resolve the reference:
CREATE ROLE DatabaseUsers;
GO
Of course, you'll need to add role members too. I suggest you manage role memberships separately rather than part of the SSDT project since those will vary by environment and many organizations have separate process for managing database access security.

Redgate SQL Source Control: ignoring Database Roles

I'm using Redgate Source Control to changetrack a database. I have a testing database from which I commit, and a production database which is the final target.
I want to have a different Database Role (the setting found of Database->Security->Roles->Database Roles) in the production database because of specific requirements. I have changed one database on my production server, but every time I deploy to the production database, the Database Role resets to the status it was before I changed it (even though the specific role is not synced).
I found a filter on Comparison Options for user roles and checked the Ignore: "User's permissions and role memberships" and deployed the filter, but the Database role still resets every time I deploy any change to production.
Is there a way to ignore Database roles or is there a workaround I could use?
EDIT:
Larnu's answer is correct.
I had a separate issue here which had to do with the role permissions not being defined in the role, but in the schema.sql file. So I had to commit the whole schema to get the role permissions committed.
In SQL Source Control, there is an option for ignoring roles entirely (or using a rule to ignore certain ones).
Select your source controlled database in the Object Explorer, and then click SQL Source Control in your toolbar. Go to the Setup Page, and then select "Edit filter rules".
Then simply untick Role and the Roles won't be source controlled any more, or you can add rules to exclude/include roles that meet said rule(s). Note you may need to remove the Role details from your Source Control repository as well, as otherwise the position of the role when you stopped Source Controlling it may be used (I suggest checking).

Azure Data Studio - Database Project - schema compare changes failed

I can successfully build my DB project in the Azure data studio with the SQL DB Projects extension. (not with SSDT but similar to this: https://www.sqlshack.com/two-ways-to-build-sql-database-projects-in-azure-data-studio/
When I right-click on the DB project and select "Update Project from database", it lists the delta between the online Azure SQL DB and the local db project.
The problem now is that when I either click on "Generate script" or on "apply", I receive an error.
Generate script: Performing script generation is not possible for this comparison result.
Performing script generation is not possible for this comparison result.
Apply schema compare changes: Object reference not set to an instance of an object.
Object reference not set to an instance of an object.
I already reinstalled the Azure Data Studio but with no success.
Any hint what I could do to fix this?
In our case these errors occur because it is added a Role Member to the Standard MSSQL Database Roles called db_datareader and db_datawriter. These roles (or objects as ADS calls them) do not exist in the local dacpac or ADS Database Project. It seems to map even if the roles are checked for update or not, so the Schema compare can't find the objects locally.
If the same applies to your project I will suggest checking if that user really needs to be a part of those two roles as they are not being mapped locally.
If you need the member in the role, a workaround is to exclude the Database Roles objects in the Schema Compare:
In Schema Compare, press Options.
In modal on the right, press the Include Object Types-tab
Find Database Roles and untick.
Press OK and re-compare.
I've set up an issue to the ADS-team, so hopefully the Schema Compare- and Database Project-responsibles can cook up a good solution on this problem.

Who created a database in my SQL Server instance?

I'm trying to determine who created a database in my SQL Server instance. The .trc logs seem to have been purged and I can't locate a backup of them. I know when the database was created and have found the .bak file that was used to create the database, but I can't determine WHO created it.
Any other ideas how I can figure this out? (SSMS schema history report also doesn't go back far enough)
Based on the following article:
There is no dbo concept for server scope securables. They are always owned by the login that created them, no matter of any server roles that the login might be a member of.
So by default, the database owner is the one who created the database, but you have to make sure that no one changed this property:
To check the database owner, in SQL Server management studio, Right click on the database and in the Properties window >> General Tab >> check the owner property:

Resources