How can I get the name of a stored procedure from within that procedure while it is executing. the procedure is written in language sql (not javascript).
CREATE OR REPLACE PROCEDURE sp_test()
returns VARCHAR
language sql
execute as owner
AS
begin
....soemthing like object_name(##procid) from ms sql server to get "sp_test" as name......
commit;
end;
You can use SHOW TRANSACTIONS. See documentation
If a procedure_A is running in a transaction, and it calls procedure_B, and then procedure_B runs a query, Then the transactions output of this query should show all three levels of queries as active transactions.
Related
I want to execute an stored procedure in Server1.DB1, this stored procedure will execute inside another stored procedure using dynamic SQL, it will be in Server1.DB2.
I need to use begin/end transaction to make sure everything is executed or everything fail.
The question is: will the transaction work in this case using dynamic SQL pointed to a the different database?
Like
BEGIN TRANSACT
--Set Status to "In Progress"
SET #Qry = N'EXEC '+ #DB2 + '.[dbo].[StatusUpdate] #Id, #Status'
SET #QryParams = N'#Id INT, #Status INT'
EXEC SP_EXECUTESQL #Qry,
#QryParams,
#Id = #Id,
#Status = #InProgress
INSERT DATA LOCALLY IN A TABLE
UPDATE DATA LOCALLY IN A TABLE
END TRANSACT
I'm using SQL Server 2014.
It depends on REMOTE_PROC_TRANSACTIONS definition:
Specifies that when a local transaction is active, executing a remote
stored procedure starts a Transact-SQL distributed transaction managed
by Microsoft Distributed Transaction Coordinator (MS DTC).
If it's ON:
The instance of SQL Server making the remote stored procedure call is
the transaction originator and controls the completion of the
transaction. When a subsequent COMMIT TRANSACTION or ROLLBACK
TRANSACTION statement is issued for the connection, the controlling
instance requests that MS DTC manage the completion of the distributed
transaction across the computers involved.
Otherwise remote stored procedure calls are not made part of a local transaction.
Several important notes:
Using distributed transaction is risky thus should be carefully used.
This feature is deprecated.
I'm not sure if this is possible but if so, my scenario would be about as simple as they come. Assuming I have 6 stored procedures called:
dbo.SyncSources
dbo.SyncData
dbo.UpdateStatistics
dbo.TruncateSourceTable
dbo.ValidateData
dbo.SearchData
None of them require any variables to be input, they simply need to be executed in the order in which they appear above. Can I create one stored procedure that will run all of them, sequentially? Keep in mind that some of the middle ones in that list take several hours to run. Also, this is on an Azure Cloud database, so SQL Server Agent is unfortunately not an option.
You can try this
create procedure OneProcedureTorunThemAll
as
begin tran
exec dbo.SyncSources
exec dbo.SyncData
exec ...
commit
it could be nice to catch errors, verify return values, etc.
I've got a database that is replicated on two servers, a live server and a test server, so that whenever it's needed the 'test' database gets overwritten by the 'live' database (so that I can reset everything if I've made a mess.)
I want an Stored Procedure in the 'test' database, that will only run in the 'test' database, but to do this I need to have it in the 'live' database as well, so that it can be copied over when 'test' is overwritten.
The procedure starts:
if ##SERVERNAME<>'TEST'
begin
raiserror ('NOT ON TEST! This SP must only be run on TEST.',16,1)
return
end
So that if it runs in live, it immediately exits.
Unfortunately the "Live" database server uses an older version of SQL, and doesn't seem to understand the lead/lag/over statements in the script, and refuses to create the procedure because of these "Incorrect syntax" errors.
The SP definitely works in the test server.
Is there a way to disregard the error messages when creating a stored procedure?
I've found a prior question that explained how to make a stored procedure with the same name, but I need the stored procedure to contain the script that the server thinks is incorrect.
The only way to not get the stored-procedure validated when created, is to run a dynamic-sql query within.
Example:
CREATE PROCEDURE dbo.YourStoredProcedure AS
BEGIN
IF ##SERVERNAME<>'TEST'
BEGIN
RAISERROR ('NOT ON TEST! This SP must only be run on TEST.',16,1)
RETURN
END
DECLARE #SQL NVARCHAR = N'
SELECT rowOne
, rowTwo
, valueOne
, LEAD(valueOne) OVER (PARTITION BY rowOne ORDER BY rowTwo DESC) AS preValue
FROM dbo.YourTable
'
EXEC(#SQL)
END
Notes:
On the long term, try to find a better strategy than DB replication for different systems. Check Continuous Deployment
Make sure to check concatenated dynamic-sql for potential issues (sql injection). Check QUOTENAME()
I have a remote stored procedure that i am running:
EXECUTE Contoso.Frob.dbo.Grobber #StartDate='20140513', #EndDate='20140518'
and this remote stored procedure returns a rowset:
EmployeeID EmployeeName StartDateTime EndDateTime
---------- -------------- ------------- -----------------------
619 Guyer, Kirsten 2014-05-13 19:00:00.000 2014-05-13 19:00:00.000
...
Excellent. Perfect. Good. Sweet.
Now that i have these results, i need to store them in a table. Any kind of table. I don't care what kind of table:
physical table
temporary table
global temporary table
table variable
I just need them stored so that i can process them. The problem is that when i try to insert the results into a table, whether it be:
a physical table
INSERT INTO EmployeeSchedule
EXECUTE Contoso.Frob.dbo.Grobber #StartDate='20140513', #EndDate='20140518'
temporary table
INSERT INTO #EmployeeSchedule
EXECUTE Contoso.Frob.dbo.Grobber #StartDate='20140513', #EndDate='20140518'
a global temporary table
INSERT INTO ##EmployeeSchedule
EXECUTE Contoso.Frob.dbo.Grobber #StartDate='20140513', #EndDate='20140518'
a table variable
INSERT INTO #EmployeeSchedule
EXECUTE Contoso.Frob.dbo.Grobber #StartDate='20140513', #EndDate='20140518'
SQL Server insists (nay, demands) that it begin a distributed transaction:
OLE DB provider "SQLNCLI10" for linked server "Contoso" returned message "The partner transaction manager has disabled its support for remote/network transactions.".
Msg 7391, Level 16, State 2, Line 41
The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "Contoso" was unable to begin a distributed transaction.
Why not just...
Now, making changes to the Contoso server is not an option. Why? Doesn't matter. Pretend that Jack Bauer will make an appearance and Guantanamo anyone who tries to modify Contoso. This means i cannot enable or reconfigure MSDTC on \\Contoso.
Did you try using READ UNCOMMITTED?
Yes.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
INSERT INTO #EmployeeSchedule
EXECUTE wclnightdb.NGDemo.dbo.tbtGetSchedule #StartDate, #EndDate
The partner transaction manager has disabled its support for remote/network transactions.
And:
INSERT INTO #EmployeeSchedule
WITH (NOLOCK)
EXECUTE wclnightdb.NGDemo.dbo.tbtGetSchedule #StartDate, #EndDate
Sorry. No nolock. Nolock is a no no:
Msg 1065, Level 15, State 1, Line 15
The NOLOCK and READUNCOMMITTED lock hints are not allowed for target tables of INSERT, UPDATE, DELETE or MERGE statements.
I always could give up on SQL Server
If i were doing this in a programming environment, it would be fairly easy to fix:
using (IDataReader rdr = ADOHelper.Execute(conn, "EXECUTE Contoso.Frob.dbo.Grobber #StartDate='20140513', #EndDate='20140518'")
{
while (rdr.Read())
{
InsertRowIntoTable(conn, rdr);
}
}
Although that would require me to create a binary, ship it, and schedule it. I'm looking for the option that works with SQL Server (so SQL Agent can schedule the job).
Bonus Reading
SET REMOTE_PROC_TRANSACTIONS (Transact-SQL)
How do I use the results of a stored procedure from within another?
How can one iterate over stored procedure results from within another stored procedure....without cursors?
SQL Server insists (nay, demands) that it begin a distributed
transaction:
If you can't configure your servers to use distributed transactions for whatever reason, you can tell it not to.
USE [master]
GO
EXEC master.dbo.sp_serveroption
#server = N'Contoso',
#optname = N'remote proc transaction promotion',
#optvalue = N'false'
GO
Or in SSMS GUI:
I don't know all implications of turning off this option, but at least now my INSERT ... EXEC [LinkedServer]... works.
Two options to try would be:
Since you already have a Linked Server set up, use it with OPENQUERY, as in:
SELECT column1, column2 FROM OPENQUERY(Contoso, 'EXECUTE Frob.dbo.Grobber #StartDate=''20140513'', #EndDate=''20140518''')
If the returned columns will remain consistent, create a SQLCLR Table-Valued Function. This assumes that the remote proc is Read-Only (i.e. SELECT-only). But unlike T-SQL functions, SQLCLR functions can execute Stored Procedures using the connection string "Context Connection = True;" as long as the Stored Procedure is SELECT-only (i.e. does not change the state of the DB through DML, DDL, etc).
How about this:
-- Either create a job that runs your remote sql via a SQLSMD command, or just run something like this:
EXEC master..xp_cmdshell 'SQLCMD -S Server\SQLSERVERDEV2005 -i"c:\DML.sql"'
(It might be easier with a job because you can modify the job step easily via sp_update_jobstep to get the right values in for your parameters)
-- Output the result of the sqlcmd into a file
-- Load the file into a table via bulk import.
I need to create a stored procedure one time and in one place only on my database server, but be able to run it from any database. However, I don't want to have to type database.schema.procedure_name every time I run it. I'd like to be able to use it like the built in procedures: sp_... is there any way to do this?
here is the procedure that I'm trying to create:
--actual procedure is more complex
CREATE PROCEDURE TestProcedure
AS
select * from sys.dm_exec_requests
go
here is how I'd like to run it from SQL Server Management Studio:
EXEC TestProcedure
--or
TestProcedure
however, you you get this error:
Msg 2812, Level 16, State 62, Line 1
Could not find stored procedure 'TestProcedure'.
everything runs fine if I run it with:
EXEC master.dbo.TestProcedure
--or
master.dbo.TestProcedure
you can run system procedures like this without any errors:
EXEC sp_help
--or
sp_help
Just create it in the master database and give it the sp_ prefix and it will work. SQL Server always checks the master database first for stored procedures (and other types of objects as well) with this prefix.
It will handle the datbase context for you as well as below.
USE master
create proc [dbo].[sp_test] as
select db_name()
GO
USE YourDB
EXEC master..sp_test /*Returns "master"*/
EXEC sp_test /*Returns "YourDB"*/
Edit:
Just following up Cade's comment to mark it as a system procedure. This seems like it might well be required in some circumstances. In SQL 2005+ you would use
EXEC sys.sp_MS_marksystemobject 'dbo.sp_test'