Access table indirectly, while still allowing to update the table - sql-server

I plan to pass exam 'Querying Microsoft SQL Server 2012'. I would like to better understand one question.
Question is:
How would you accomplish this task?
You work as a database developer
at ABC.com. ABC.com has a SQL Server 2012 database named SalesDB with
a table named Invoices. Application developers are developing several
in-house applications that will access the Invoices table. You need to
develop a solution that will allow the applications to access the
table indirectly while still allowing them to update the Invoice
table. How would you accomplish this task?
possible answers are.
A. You should create a view on the Invoices table.
B. You should create a columnstore index on all columns used by the
applications.
C. You should allow the applications access to the Invoices table via
stored procedures.
D. You should drop and recreate the Invoices table as a partitioned
table. Possible answers are
This is source: How would you accomplish this task?
They say that correct answer is C, but I don't know why? I think that correct is A, because view works 'indirectly' with data.
Thank for help.

The commented ownership-chaining of stored procs only come into place when the stored proc and the used tables have the same owner.
So I would like to point out another argument.
You can EXECUTE a stored proc AS another user. That means you could create a user without a login and grant UPDATE permissions. Let's say the name of the user is UPDATEInvoices. When you create a stored proc you can define that it has to execute as the comtext of the user.
So, when you give the user who wants to call the stored proc EXECUTE permissions he can UPDATE rows in the table because it runs with other permissions.

Related

How to create temp tables in SQL to be used in several ADF activities?

I need to create a global temp table in my SQL Server while executing an Azure Data Factory pipeline. This table will be used in several activities.
I already tried several approaches including one using the Stored Procedure activity targeting the sys.sp_executesql SP and the CREATE TABLE statement as the parameter. With this approach the table is actually created, but it's automaticaly dropped a second later, I don't understand why.
This is the script used to create the temp table:
CREATE TABLE ##tempGL
(
GLAccount NVARCHAR(15),
GLSubAccount NVARCHAR(15)
)
So, how can I create a SQL Server temp table from an Azure Data Factory Pipeline activity that persists until I dropped it?
I have been struggling with this myself. Apparently this is by design (see quote below from Microsoft employee) and it is not possible to achieve this using Azure Data Factory even though the documentation mentions that it is possible.
That is by design. We won’t keep connection between 2 activities.
If you use a real table instead of temporary table. Then you will get the expected result.
The suggestion is don’t used temporary table in ADF if the data need more than 1 activities to access.
https://github.com/MicrosoftDocs/azure-docs/issues/35449#issuecomment-517451867
The reason this happens is the session is dropped when a pipeline activity ends, which causes the temporary table to also be dropped.
Global temporary tables are automatically dropped when the session that created the table ends and all other tasks have stopped referencing them. The association between a task and a table is maintained only for the life of a single Transact-SQL statement. This means that a global temporary table is dropped at the completion of the last Transact-SQL statement that was actively referencing the table when the creating session ended.
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql?view=sql-server-2017#temporary-tables
Hopefully Microsoft fixes this at some point and makes it possible to use temporary tables across activities with Azure Data Factory.
I have raised this as a suggestion for Azure here https://feedback.azure.com/forums/270578-data-factory/suggestions/38287108-persist-global-temporary-tables-between-activities
For anyone reading this that might want his feature please upvote that suggestion.

Sybase ASE tempdb table permission issue

I know sybase supports two types of temp tables, one starts with # and can't be shared by sessions. The other one is created with tempdb.. prefix which can be shared by sessions or users.
My question is:
Are tables created in tempdb accessible to other users as well?
How to control the access or how to prevent the table created by userA from being modified/dropped by userB?
I googled for a while but didn't find any information on this.
I'm using sybase at work but don't have admin access to create new user so I can't do the test.
Can someone who have experience please advise?
please refer to http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc32300.1570/html/sqlug/X10118.htm for details.
i also test the behavior on sybase ase 15.7.
the result as same as the previous link.
Are tables created in tempdb accessible to other users as well?
Yes.
How to control the access or how to prevent the table created by userA from being modified/dropped by userB?
There seems no method about the tempdb..xxx tables.

Not allowing deletion of records by any user except through stored procedure

I am working on a project and in one of my tables I want users (any user) not to be able to delete rows, unless deletion is done through a stored procedure.
There is a question about this and has an answer here https://stackoverflow.com/a/366931/4810628
But I need to know how to enforce such policy in SQL Server.
Thanks
remove (DENY) everyone's permissions to do deletes to the table, add (GRANT) them permissions to execute the stored proc.

Enable/Disable stored procedures

I am working with a large group of stored procedures (~300) in SQL Server 2012 Web Edition and I need to enable/disable some of the stored procedures at various times.
Is there a way to create a sub-folder under "Programmability" in SQL Server Management Studio to place inactive stored procedures in? If not, is there an option to enable/disable a specific stored procedure without removing it from the database? Since I frequently need to enable/disable I would rather not remove the procedure and then re-script it when it is needed?
Create those stored procedure in a separate schema (use CREATE SCHEMA) and then GRANT or REVOKE execution right on all stored procedures in that schema for the users in charge.
As a suggestion, you can have contract in naming for example spTest is enables and spTest_Disabled is the same one which is disabled, so you can write another storedprocedue with this sugnature spChangeSpStatus(spName,state) this sp uses sp_rename to rename the procedure to new one,(I mean adding _disabled to its name or remove _disabled form the name)
I hope this helps
You can't create a subfolder, but can create another schema. Name it whatever you like (say inactive) and set permissions on it appropriately.
Then write a script to move objects from the working schema (say dbo) to inactive:
alter schema inactive transfer dbo.proc
There is an inexpensive tool called SQLTreeo that allows you to create folders in the Object Explorer. If I remember correctly, there are two modes of operation, one that allows each user with the tool to have their individual folder structure, and another that imposes a common folder structure appear on all machines that have SQLTreeo installed.
Create a new table to manage your SP, and in each SP just add an IF that always ask for the table created dbo.ManagerSP if that sp is Active=true, if true the SP runs,,,if not,,,not runs,,
And with that for control all your SP just need run an UPDATE of active status in dbo.ManagerSP

Determing if stored procedure can execute based on AD login

I have a stored procedure that updates data in a table for a specific record. I have several users who will be making use of this stored procedure however I only want to them to be able to update records that are assigned to them.
Each record that is to be updated by the stored procedure has a field named "UserID" which define who has control over the record. I also have a mapping table that maps active directory logins to the UserID's.
I am using Active Directory so SQL Server knows who is attempting to execute the stored procedure. Is there a way within the stored procedure to look-up the users active directory login in another table and then determine if they have access to the records attempting to be updated?
You can find out who the current user is in the proc by calling SYSTEM_USER and incorporating that into the query that updates the rows.
Does this article help? Granting Row-Level Permissions in SQL Server
It recommends the following steps
Create the table, adding an additional column to store the name.
Create a view that has a WHERE clause based on the user name column. This will restrict the rows returned to those with the specified value. Use one of the built-in functions to specify a database user or login name. This eliminates the need to create different views for different users.
Create stored procedures to select, insert, update, and delete data based on the view, not the base tables. The view provides a filter that restricts the rows returned or modified.
For stored procedures that insert data, capture the user name using the same function specified in the WHERE clause of the view and insert that value into the UserName column.
Deny all permissions on the tables and views to the public role. Users will not be able to inherit permissions from other database roles, because the WHERE clause is based on user or login names, not on roles.
Grant EXECUTE on the stored procedures to database roles. Users can only access data through the stored procedures provided.
I'm no application designer but on the surface, your solution sounds unnecessarily complicated to me.
That said, you can issue the following query to get the Windows AD Login name of the user currently executing the stored procedure. You can use this information to cross reference with your mapping table to determine if the AD account has the required privileges to perform the operation.
SELECT SYSTEM_USER
Do keep in mind that this returns the name of the currently executing context, so keep in mind that this can be explicitly changed using the "Execute As" statement.
EDIT:
I wonder if perhaps a view could be used to limit the data visible to a given AD account. The Stored Procedure logic could then focus on the data modification aspect, rather than security implementation. Controlling your data access using views would also ensure that a consistent security access method is used across multiple stored procedures if required, as opposed to having to implement security checking within each.
Since writing this, the link provided by Martin Smith, details how this solution can be implemented:
Granting Row-Level Permissions in SQL Server
In conclusion, a combination of both is how Microsoft suggest you implement the solution to your problem.

Resources