Is "execute as" mandatory in natively compiled stored procedures? - sql-server

I noticed that all examples (that I've seen) of natively compiled stored procedures (in SQL Server) are defined using EXECUTE AS OWNER.
For example:
CREATE PROCEDURE [dbo].[InsertOrderXTP]
#id INT,
#date DATETIME2,
#status TINYINT
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS...
We started getting the following error while trying to execute natively compiled stored procedures we created with EXECUTE AS OWNER:
Could not obtain information about Windows NT group/user ...
This make sense because we had other un-related technical issue with the user that created those procedures.
Since we never used EXECUTE AS .. in regular ("interpreted") procedures, I tried removing it from the natively compiled stored procedure and it seems to to be working just fine.
But as I mentioned, it contrast from all the examples I've seen, and I couldn't find any relevant documentation that elaborates on this issue.
Must a natively compiled stored procedures be created with EXECUTE AS OWNER..."?
Is there a benefit to creating natively compiled stored procedures with EXECUTE AS OWNER... that doesn't exist in regular (interpreted) stored procedures?
Where can I find explicit documentation about this issue?

This appears to be a historical limitation that is no longer required as of SQL Server 2016.
In the documentation for CREATE PROCEDURE, we have this note:
For natively compiled stored procedures, starting SQL Server 2016 (13.x) and in Azure SQL Database, there are no limitations on the EXECUTE AS clause. In SQL Server 2014 (12.x) the SELF, OWNER, and 'user_name' clauses are supported with natively compiled stored procedures.
Then on the separate page about EXECUTE AS there is this:
CALLER is the default for all modules except queues, and is the same as SQL Server 2005 (9.x) behavior.
Put those two things together, and we find that omitting the EXECUTE AS clause on a natively compiled stored procedure in SQL Server 2014 would have defaulted to an unsupported option. So all examples of natively compiled stored procedures which predate SQL Server 2016 would have needed an explicit EXECUTE AS clause to compile successfully.

Related

Does sp_dropextendedproc drop both system-defined and user-defined extended stored procedures?

I'm a student and the SQL Server 2016 documentation that I'm going through is not very clear. And the online help that I saw I think it refers to SQL Server 2017 https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-dropextendedproc-transact-sql
Regards
The article says
In SQL Server 2017, sp_dropextendedproc does not drop system
extended stored procedures. Instead, the system administrator should deny
EXECUTE permission on the extended stored procedure to the public role.
Which is true, but seems to suggest this is something new in SQL Server 2017. This is not the case; it's an inappropriate search-replace based on the current version. The Books Online help for SQL Server 2005 (since removed online, I think) says this (emphasis mine):
In SQL Server 2005, sp_dropextendedproc does not drop system extended
stored procedures. Instead, the system administrator should deny
EXECUTE permission on the extended stored procedure to the public
role. In SQL Server 2000, sp_dropextendedproc could be used to drop
any extended stored procedure.
And this, unlike the current version, makes it clear what's going on. Sometimes Microsoft's obsession with removing documentation for products that are no longer supported goes a little too far.

Creation of stored procedures in SQL Server

I'm working on a fairly large application in which a database schema (tables, stored procedures, etc) is created by running a SQL script. The script is invoked from a stored procedure via xp_cmdshell like this.
CREATE PROC CreateNewScheme AS
BEGIN
...
EXEC xp_cmdshell 'osql createschema.sql -U username ...'
...
END
This stored procedure is run once during program initialization and again by SQL Server Agent during a scheduled job.
For security purposes we are required to disable xp_cmdshell. My first inclination was to just insert all of the schema creation commands into the existing stored procedure so it can be that can be executed as needed. However, this approach will not work because SQL Server does not support creation of stored procedures from other stored procedures.
One alternative might be to call the schema creation script from an external application rather than from a SQL script, but that's requires a fairly large rewrite, which we're trying to avoid if possible.
Is there a way to accomplish this with minimal changes?
My first inclination was to just insert all of the schema creation commands into the existing stored procedure so it can be that can be executed as needed. However, this approach will not work because SQL Server does not support creation of stored procedures from other stored procedures.
If you really need to wrap creation of stored procedures inside another store procedure you could wrap it with dynamic SQL:
CREATE PROC CreateNewScheme AS
BEGIN
EXEC('CREATE PROCEDURE myfirstproc AS ...');
EXEC('CREATE PROCEDURE mysecondproc AS ...');
END
Of course you will have to escape every ' inside dynamic SQL.
Another way is to exeute osql directly from SQL Server Agent job:
You should check if SQL Server Agent Account have sufficient privileges or create proxy.
EDIT:
If you cannot use SQL Server Agent, use Windows Task Scheduler to run osql:
Start Task Scheduler
Schedule a Task
We are in the same situation like you, whereby we want to disable xp_cmdshell, which we used for a couple of things on our production servers.
What we did was to create SQLCLR methods for the operations that xp_cmdshell performed in our environment. Sure, the assembly had to be created as UNSAFE, but the methods could only be called for the individual operations, and the methods had a lot of validation code, so that we didn't do anything "stupid".

How to log to an external file from SQL Server 2016

I have a 3rd party software which calls a stored procedure in my SQL Server to insert log entries. I would rather have the log entries write directly to a txt file instead of being in a SQL Server table.
I have tried collecting the entries in a ##temptable and using BCP to write them out but ran into an issue. The 3rd party software wraps all calls to the stored procedure in a transaction which causes BCP to hang during exports.
I thought about using a ##temptable and having a SQL Server Agent job dump it on a regular interval but the transactions can be long running and I'm not sure how to make sure I can write entries to the text files without duplicate or missing rows depending on transaction lengths.
Is there a good way to write from a stored procedure into a file? If so, is there a way to batch the writes over multiple calls of the stored procedure?
To access resources being out of SQL Server control from TSQL batch you can use a CLR Stored Procedure. With it you can write some .NET code to do anything you want with for example files or network connection. Then you have to prepare a DLL assembly and connect it with SQL Server. Here you are an example from MSDN how to create a procedure from external assembly:
CREATE ASSEMBLY MyFirstUdp FROM 'C:\Programming\MyFirstUdp.dll';
CREATE PROCEDURE HelloWorld
AS EXTERNAL NAME MyFirstUdp.StoredProcedures.HelloWorld;
EXEC HelloWorld;
More information about CLR Stored Procedures (and presented example) you can find on https://msdn.microsoft.com/pl-pl/library/ms131094(v=sql.110).aspx

where is SP_EXECUTESQL defined?

The 'SP_' prefix by convention suggests a system stored procedure. But nowhere in my SQL Server instance could I find the sp_executesql stored procedure.
I know it is there because it is used by one of my workplace's legacy code. But where is it? Where can I find it using MS SQL Server Management Studio?
Where can I find it using MS SQL Server Management Studio?
It is an extended stored procedure and you can't do anything useful with it having found it though (apart from managing permissions).
master --> Programmability --> Extended Stored Procedures --> System Extended Stored Procedures
It is present there , if you execute this query
`sp_helptext sp_executesql
you will get (Server Internal) because "sp_helptext" is a extended stored procedures so you cannot see it. They are processed in a dll rather than TSQL..
Refer this link
https://technet.microsoft.com/en-us/library/ms175200%28v=sql.105%29.aspx

SQL Server: INSERT/UPDATE/DELETE failed because the following SET options have incorrect settings: ‘QUOTED_IDENTIFIER’

I have this rather awkward problem:
For two weeks now, whenever after I've updated/created stored procedures using my SQL scripts, when these stored procedures are run, they fail with above error.
Other posts dealing with this problem didn't help in my case.
Here's a number of parameters, helping to exclude common solutions which do not apply in my case:
My stored procedure scripts work flawlessly on my laptop (SQL Server 2012, Windows Server 2008 R2).
My stored procedure scripts correctly create stored procedures on any other machine (which is our build machine, with SQL Server 2012 installed; our TEST server, with SQL Server 2005 installed, and our PROD server, with SQL Server 2005 installed). However, the stored procedures won't run on any other machine than mine.
I'm using a database backup of our production SQL Server (SQL Server 2005) on my machine (like any other machine here does).
Even the most basic stored procedure fails (e. g. DELETE myTable WHERE ID = #delID).
On every SQL Server installation I've checked, quoted identifier is set to OFF (!), both on server and on database level. So why do my stored procedures all of a sudden require to have this option set to ON?
I'm using SQLCMD to run my scripts. This gives me an option to dynamically set the server instance's database name in the USE statement.
My scripts only contain a USE statement and right after the ALTER PROCEDURE; or alternatively IF EXISTS (...) DROP PROCEDURE ... GO; CREATE PROCEDURE ...
This all worked for years now, but suddenly, since two weeks ago, stored procedures created with my scripts suddenly fail.
I know that I could manually set QUOTED_IDENTIFIER to ON in my scripts - but I don't want to. There is something wrong here. I want to know what that problem is.
What's happening here?
SQLCMD sets the QUOTED_IDENTIFIER option to OFF by default. You can change it with -I option.
Could it be that your stored procedure is now doing something on a table that has had an index added? I've had the same issue, and it's due to a new index on a computed column.

Resources