SSDT - specify authorization user on schema create - sql-server

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.

Related

groovy code to create database with no build id

At present, we are supposed to provide a tenant id to create net new database for a tenant . But there is no way to create net new databases for the default tenant. Initially it was agreed to create the default tenant database with "_system" but later it got changed and there is no support to create the default tenant db.
I need groovy code to create database with no tenant id.
I understand your question now. When you run your app, your app will create a database and with a suffix like "_100" added to the name of the database. You don't want the suffix added anymore.
When you run a Grails app, it does not create a database for you. You will have a database created ahead of time yourself.
If you said the app did create a database, your programmer might have a SQL script somewhere in your app.
You must have something like this in your source code .executeUpdate("CREATE DATABASE IF NOT EXISTS MyDatabaseName")
See if you can find this SQL and change it.

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.

DACPAC SQL Server dropping schema permissions

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.

What are good practices for granting database permissions to a web service connection?

I have been searching for articles and SQL script examples that would demonstrate how to securely and conveniently solve one of the most common scenarios - connecting from a .Net Core Entity Framework based web application to an SQL database.
But somehow I could not find any coherent step-by-step guide from a reputable source.
Let's assume the following:
I cannot use integrated Windows auth in the connection string and must use username and password based auth (because hosting on a Linux server and the DB is on a different Windows server)
the web service will need your usual minimum set of permissions - connect to the database, read data, write data, delete data, execute stored procedures
While reading many tutorials, I find there are multiple ways to manage the connection permissions. To avoid this question being too broad, I'll list my current choices as I understand them (please correct me if I'm missing something).
Users and logins:
create a login and a user for the database
create a database-only user without a login (not sure if this is applicable to a web app and connection string, but still it's a feature that I've seen being used)
Assigning permissions:
assign the user to some fixed SQL role (db_datareader, db_datawriter AND also will have to grant EXECUTE permission)
grant all fixed permissions
create a custom role (let's say, db_web_apps) with required permissions
Which choices are better (more secure and easier to manage in general) and recommended by SQL DBAs?
I think every database administrator should have a template script handy for quickly adding a new user with minimum required permissions every time when developers ask for a new connection for their shiny new web app.
If you know a good, reliable tutorial or GitHub / Gist example that explains what and why is being done that way or a script that you yourself have used for years without any issues in production environments, I'll really appreciate if you could share it.
Create a role in the database and assign the required privileges to the role. Don't use the fixed database roles. Instead grant permissions directly to objects, schemas, or the entire database if necessary. Like this:
create role trusted_app_role
grant select, insert, update, delete, execute
on schema::dbo to trusted_app_role
That will grant the role full DML permissions on all the objects in the default dbo schema. So if you have any tables or procedures you don't want the app to have access to, just create them in a different schema, say, admin. This way you never have to fiddle with permissions as you add objects. The fixed database roles predate schema-based permissions, and aren't really needed any more.
For your application's identity, add Active Directory or Azure Active Directory (Azure SQL) identities to this role, or, if you can't, add SQL Users to the role.
If you are on Azure SQL, you should normally use a database user without a login. On SQL Server you can only add "contained database users" if you enable Partial Database Containment. Which you can do, but is incompatible with Change Tracking and Change Data Capture, so it's a tradeoff.
So normally for SQL Server you still create a login and map the user to the login. EG:
create login web_service_user with password = '5X+jeuAB6kmhw85R/AxAg'
create user web_service_user for login web_service_user
And then add that user to your role
alter role trusted_app_role add member web_service_user

Visual Studio 2010 - Database Project with imported database fails to build

I'm looking at the Database Project in VS2010, the idea being that I want something I can use to keep track of the database schema (in source control) and the ability to generate "new install" scripts, and change scripts.
When I create a new database project wizard and import my existing database schema, it won't "build". I get the error:
SQL03006: User: [scanner] has an
unresolved reference to Login
[scanner].
The SQL that generates this error:
CREATE USER [scanner] FOR LOGIN
[scanner];
The user "scanner" is a login defined in the database I imported. I have no idea what it's teling me, and google isn't throwing much up. Any ideas?
The Login is actually defined in the master database of the server install. The CREATE USER statement needs to point at an existing Login otherwise it errors. The Database Project is not aware of the Login at the server level. Either you can create a Server Project to handle the Logins, or you can turn off the checking of Security objects in your Database Project. See the answer by Demetri M for more details: http://social.msdn.microsoft.com/Forums/eu/vstsdb/thread/1f8226fe-b791-4344-8735-3d38307e8664
I'm using Visual Studio 2012 for a SQL Server 2008 R2 database project. The options listed by #Judah don't appear to work anymore.
They now appear to be Settings that you configure while doing a Schema Compare:
Right click database project >
Choose 'Schema Compare' >
Choose the 'Settings' gear icon >
Choose the 'Object Types' tab >
Logins are Non-Application-scoped. Database roles, Permissions, Role Memberships, and Users are all Application-scoped.
Unfortunately, the only way that I can find to preserve these is to save the schema compare. This can be a little inconvenient if you're sharing this on a team and would like project/database (or server) settings for any schema compare.
It gets the job done, though.
You can change the create user scripts to create roles.
So instead of "Create user userName for login loginName;"
use "Create Role [userName] authorization dbo;"
This is a hack, but as long as you aren't having to deal with users and roles in your project, you can happily do the following:
GRANT EXECUTE
ON OBJECT::[dbo].[sp_name] TO [userName];
Apparently, this issue is still occurring on VS2017 database projects as well.
I've managed to solve it by first creating the login and then create the user.
-- Windows Account
CREATE LOGIN [Domain\Username]
FROM WINDOWS WITH DEFAULT_LANGUAGE = [us_english];
GO
CREATE USER [Domain\Username] FOR LOGIN [Domain\Username];
GO
-- Sql Acccount
CREATE LOGIN [sql_account] WITH PASSWORD = 'Ch#ngeth1spA$swurD'
GO
CREATE USER [sql_account]
FROM LOGIN [sql_account]
WITH DEFAULT_SCHEMA = dbo
GO
-- Then set the sql file Build Action to "Build"
In the database project open the 'Security' folder (assuming that's how your database was imported). For each user profile that is causing an issue, set the build action to 'None' in the properties panel. You will also have to remove them from any other files in which they appear, including Permissions.sql and RoleMemberships.sql.

Resources