How to know the last database before a procedure (in another database) was called - sql

The caller of the procedure who is in database AAA:-
use AAA
exec BBB.dbo.ap_MyProc
The procedure being called which is in database BBB:-
use BBB
create procedure ap_MyProc as
print 'We want a way to return the database name AAA'
Any advice would be appreciated.

Well i can now answer my own question. We can exploit syslockinfo...
declare #db_name varchar(255)
select
#db_name = db_name(rsc_dbid)
from
master.dbo.syslockinfo
where
req_spid = ##SPID
and req_ownertype = 4 --"exSession"
and rsc_dbid <> db_id()
select #db_name = isnull(#db_name, db_name())
print #db_name
Works in SQL 2008 as well. :)

Can your stored procedure be edited? If yes, I think you can edit the stored procedures and add one more parameter for the database name.
And during calling the stored procedure, you should pass the db_name() into the new parameter, so that your stored procedure could know which database is calling it
DECLARE #ServerName varchar(50) = db_name()
EXEC [dbo].[SP] #newParams = #ServerName

Related

Stored procedure execution order

Thanks for your time, is there a way to execute the create database part of the statement before the use database name?
I guess I could create 2 set and execute statements but there must be a better way ?
CREATE PROCEDURE [dbo].[Master]
#DBNAME NVARCHAR(50)
AS
DECLARE #CODE NVARCHAR(MAX)
SET #CODE = 'CREATE DATABASE '+#DBNAME+'; USE '+#DBNAME
EXEC SP_Executesql #CODE
Thanks in advance

How to create a simple stored procedure with table name as an input

I am using SQL Server 2017 and I would like to create a stored procedure with a single table name as an input variable. All I want the procedure to do is update that table in a variety of ways. This project will be done twice a year, and the columns will always be the same, so I would like to try this as a stored procedure, so I do not have to highlight several lines of code and executing each time.
Is there a simple way to pass a table name through a stored procedure which updates the table (adding columns, calculating columns, replacing nulls in columns etc). In a basic example, one task would be just replaces nulls with 0s in a column. I am not sure how to set this up though. DO I have to declare every column in the table too?
CREATE PROCEDURE updteleform
#tablename TABLE
AS
BEGIN
UPDATE #tablename
SET Recog = 0
WHERE Recog IS NULL
END
GO
I'm assuming you want to update a physical table. SQL Server table variables don't work that way, rather they are a way to pass a transient result set to a stored procedure. There is no persistence if your stored procedure does not do so.
If you are looking to update the same table, then just write the procedure to work on that table.
If you are looking to update multiple tables using the same script then you should change your procedure to accept a string parameter that would be the name of the table you want it to work on and then use dynamic SQL in your stored procedure.
Something like
CREATE PROCEDURE updteleform #tablename sysname
AS
BEGIN
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'
update ' + QUOTENAME(#tablename) + '
set Recog= 0
where Recog is null;';
EXEC sp_executesql #sql;
END
GO
And then call it with something like:
EXEC updteleform #tablename = 'table1';
EXEC updteleform #tablename = 'table2';
EXEC updteleform #tablename = 'table3';
...

Parametrizing input using sql server?

I want to parametrize my stored procedure's input to prevent sql injection. The problem is MY database has no application(It's just for school) & as there's no client language like C# etc, I have to do it with sql itself. i did this
ALTER procedure [dbo].[drop_tt]
#ss varchar(40)
as
EXEC sp_executesql N'SELECT *
FROM tt
whERE ss = #Ss', N'#ss varchar(40)', #ss
but when I execute this statement the tt table was droped :(
exec drop_tt 'www';drop table tt--'
anyone can help?
In short: why are you altering sp? you just need to create a parametrized stored procedure like:
CREATE PROCEDURE uspGetAddress #City nvarchar(30)
AS
SELECT *
FROM AdventureWorks.Person.Address
WHERE City = #City
GO
Just look at this very simple tutorial , you don't need to alter your procedures.
Edit: my approach would be to get rid off the statement EXEC sp_executesql and naming that starts with drop. Just try to simplify your stored procedure execution statement in the body.

execute stored procedures returned from database table

I am working with sql server 2008
I have a database table that has a column containing a stored procedure name.
I want to query the database table which returns a list of the stored procedure names, and execute them.
The stored procedures are similar all having a select statment. The data returned in this select statement I want to insert in to a data base table.
Pseudo code looks like this:
INSERT INTO MyTable
EXECUTE sp_executesql SELECT StoredProcedureName FROM Table
Anyone able to assist me with correct sql for achieveing the above?
sp_executesql accepts a unicode string not a tsql statement. So you would need to execute your procedure(s) like this:
execute sp_executesql 'execute ' + #storedprocedurename
which will execute a single procedure.
You will need to write some iterative process to populate the #storedprocedurename variable from your source table.
This is pretty much same as #Coltech answer just with cursor.
DECLARE #spname VARCHAR(200)
DECLARE #sql VARCHAR(1000)
DECLARE your_cursor CURSOR FOR
SELECT spname
FROM yourTable;
OPEN your_cursor;
FETCH NEXT FROM your_cursor
INTO #spname;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = 'EXEC ' + #spname
execute sp_executesql #sql
FETCH NEXT FROM your_cursor
INTO #spname;
END
CLOSE your_cursor;

Execute stored proc with OPENQUERY

I have SQL Server 2008 with a linked Sybase server and I am trying to execute a stored procedure on the Sybase server using OPENQUERY. If I have a stored proc that doesn't take parameters it succeeds fine. If I have a stored proc with parameters it fails. I even tried a very basic stored proc that only took an int an that still failed. Below is the syntax I am using:
select * from
OPENQUERY([LINKSERVER],'exec database.user.my_stored_proc ''AT'',''XXXX%'',''1111'',1')
Msg 7357, Level 16, State 2, Line 3
Cannot process the object "exec database.user.my_stored_proc 'AT','XXXX%','1111',1". The OLE DB provider "ASEOLEDB" for linked server "LINKSERVER" indicates that either the object has no columns or the current user does not have permissions on that object.
As the proc will execute just fine without parameters, I don't think it is a permission issue.
This worked for me,
SELECT * FROM OPENQUERY(LOCALSERVER, 'SET FMTONLY OFF EXEC snr.dbo.GetAllSignals #controlRunId = 25, #experimentRunId = 26')
I was creating temporary tables, and that's why i got access denied
Here is more info http://www.sommarskog.se/share_data.html#OPENQUERY
I create a sp that doesn't return any value and it doesn't work.
Your SP in mysql have to return a value!
for example I do this in "mysql":
CREATE DEFINER=`root`#`localhost` PROCEDURE `MyPro`(IN `Name` VARCHAR(50), IN `Id` INT, OUT `Result` INT)
MODIFIES SQL DATA
BEGIN
DECLARE Result INT;
SET Result = 0;
INSERT into MyTable (Id,Name) VALUES(Id,Name);
SELECT Result;
END
That "Id" and "Name" is input parameter and "Result" is output parameter
and create linked server in SQL SERVER and call it like this:
select * from openquery
(
Test,'call mydb.MyPro(''Name'',''16'', #P0);'
)
It works for me :D
Linked Servers and OPENQUERY, Gems to MS SQL Server...that are wolves in sheep clothing. I've found the following solutions to work when dealing with parameters
If the SP is basically just SELECT statements, the move the same to a VIEW and just pass SQL statements via OPENQUERY.
Build the OPENQUERY as a string and then use execute_sql.
You could also see if it works to precede exec with SET FMTONLY ON:
OPENQUERY([LINKSERVER],'SET FMTONLY ON; exec database.user.my_stored_proc ''AT'',''XXXX%'',''1111'',1')
If you try this and it works, you should probably Google FMTONLY+OPENQUERY to get an idea of what it means.
Try this,
SELECT * FROM OPENQUERY(linked_server_name, 'SELECT postgres_procedure_name (parameters)');
I experienced a very similar issue, but my SP wasn't taking any parameters.
I tried experimenting with altering the query sent through the openquery to include 'SET NOCOUNT ON' and 'SET FMTONLY OFF' but this had no difference.
The only solution that worked for my stored procedure was dropping the existing version, and altering the code to specifically 'SET NOCOUNT ON'
After doing this I was able to successfully run my stored proc through my linked server connection.
First of all you have to add hard code text fields then you have to
replace it by your parameters value like FromDate,TillDate,EmpID,CompCode,0,DeptID,DesgId,LocationID,AtnType
DECLARE #startdate varchar(255) = '2019-12-17'
DECLARE #enddate varchar(255) = '2019-12-17'
Set #SQL = 'SELECT * FROM OPENQUERY(' + quotename(#LinkedServer) + ',' + '''' +
'SET FMTONLY OFF; exec [TAP].[dbo].[GetAttendanceList] ' + 'FromDate,TillDate,EmpID,CompCode,0,DeptID,DesgId,LocationID,AtnType,1'')'
You have to replace your parameters values shown below
set #SQL=REPLACE(#SQL,'FromDate',+''''+''''+#startdate+''''+'''')
set #SQL=REPLACE(#SQL,'TillDate',+''''+''''+#enddate+''''+'''')
set #SQL=REPLACE(#SQL,'CompCode',+''''+''''+#CompCode+''''+'''')
set #SQL=REPLACE(#SQL,'AtnType',+''''+''''+''''+'''')
if #EmpID is Null
begin
set #SQL=REPLACE(#SQL,'EmpID','null')
end
if #DeptID is Null
begin
set #SQL=REPLACE(#SQL,'DeptID','null')
end
if #DesgId is Null
begin
set #SQL=REPLACE(#SQL,'DesgId','null')
end
if #LocationID is Null
begin
set #SQL=REPLACE(#SQL,'LocationID','null')
end
print #SQL
exec ( #SQL)