Using SQL Profiler to get the name of stored procedures - sql-server

I have a database (SQL server 2000) with almost a thousand of stored procedures and I want to know which stored procedure is called after a button is clicked.
I try to use SQL Profiler (version 8.0) to capture the name of the stored procedure, but it seems it's not possible to get the name directly from SQL Profiler.
A tutorial says I can get the stored procedure name by running:
Select name from sysobjects where id = <ObjectID>
I tried but the id matched nothing.
How can I get the name of the stored procedure?
Thanks

This small query can give you a preview (the first 8000 characters) of your database T-SQL code (Procedures, Functions, Triggers, etc):
select o.id
,case
when parent_obj = 0
then ''
else '[' + Object_Name(parent_obj) + '].'
end + o.Name as Name
,c.text
,xType as Type
from syscomments c
join sysobjects o on (o.id = c.id)
where ColId = 1
and Category = 0
order by o.xType
,name
,c.Colid

Related

Check if stored procedure modifies table data in SQL Server

I am granting a user group permissions to execute all stored procedures in a database which contain the word "Report" or "PDF", on the condition that the execution of these stored procedures will not modify the data in the database.
Now, I am currently reading through each of these stored procedures one at a time and basically doing a code review on each of them with the intention of determining if they modify data, or if they simply retrieve data.
Is there a programmatic way to test for the modification of the database in a single-run procedure that only gets run when the programmers want it run?
You can get this information from the sys.dm_sql_referenced_entities system function. is_updated will be 1 when any table is inserted, updated or deleted.
SELECT
schema_name = s.name,
p.name,
is_updated = CAST(
CASE WHEN EXISTS (SELECT 1
FROM sys.dm_sql_referenced_entities(QUOTENAME(s.name) + '.' + QUOTENAME(p.name), 'OBJECT') r
WHERE r.is_updated = 1)
THEN 1 ELSE 0 END
AS bit)
FROM sys.procedures p
JOIN sys.schemas s ON s.schema_id = p.schema_id
WHERE (p.name LIKE '%Report%' OR p.name LIKE '%PDF%')
AND p.is_ms_shipped = 0;
db<>fiddle
You can look for words like INSERT, UPDATE,DELETE... in the stored procedure code, here's an exmple of the query :
SELECT *
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%INSERT%'
OR OBJECT_DEFINITION(OBJECT_ID) LIKE '%UPDATE%'

SQL - Replacing connection strings for multiple stored procedures

I'm looking to replace connection strings across multiple stored procedures.The development database I'm working with is restored from production and stored procedures within contain connection strings to a production linked server. My aim is replace the linked server connection strings to point at a development linked server for testing purposes. I'm looking to automated this as a step in the SQL Agent restore job to run immediately after the restore.
The issue I'm having is setting the stored proc definition as a variable while keeping the formatting. When selecting the definition text, the stored proc is all on one line so after replacing the CREATE for ALTER along with the connection stings I cannot execute the SQL due to the formatting. I've tried playing around with STRING_SPLIT as but to no avail. Is there a way to do this or is it not possible?
Here is an example of part of one of the procedures
SELECT
a.AgreementNumber,
a.AgreementProposalID,
c.CustomerNumber,
pc.Id CustomerID,
a.AgreementCreateDate
INTO
#a
FROM
SENTINEL.DotDot_S3DB01_Replica.dbo.AgreementTable a
INNER JOIN
SENTINEL.DotDot_S3CUSTDB_Replica.dbo.CustomerTable c ON a.AgreementCustomerNumber = c.CustomerNumber
INNER JOIN
SENTINEL.DotDot_Proposal_Replica.dbo.Customer pc ON pc.Code = c.CustomerNumber
WHERE
a.AgreementCreateDate > #LastEnteredDate;
After my changes it needs to look like this to reference the test database names
SELECT
a.AgreementNumber,
a.AgreementProposalID,
c.CustomerNumber,
pc.Id CustomerID,
a.AgreementCreateDate
INTO
#a
FROM
SENTINEL.DotDotUAT_S3DB01.dbo.AgreementTable a
INNER JOIN
SENTINEL.DotDotUAT_S3CUSTDB.dbo.CustomerTable c ON a.AgreementCustomerNumber = c.CustomerNumber
INNER JOIN
SENTINEL.DotDotUAT_Proposal .dbo.Customer pc ON pc.Code = c.CustomerNumber
WHERE
a.AgreementCreateDate > #LastEnteredDate;
I've tried using this code to select the stored procedure code as a variable so I can execute the alter procedure command with the changes however the object definition selected from sys.procedures is displayed all on one line.
DECLARE #SQL VARCHAR(MAX)
SET #SQL = ( SELECT OBJECT_DEFINITION(object_id)
FROM sys.procedures
WHERE name = 'Usp_Proc')
SET #SQL = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(#SQL,'CREATE','ALTER'),'OriginalString','ReplacementString'),'OriginalString','ReplacementString'),'OriginalString','ReplacementString'),'OriginalString','ReplacementString')
EXEC (#SQL)

Getting Oracle stored procedure parameters

I have a query in a SQL Server database that gets stored procedures parameters like this:
SELECT
parameter.name,
types.name,
types.is_nullable
FROM
sys.parameters AS parameter
INNER JOIN
sys.procedures AS procedures ON parameter.object_id = procedures.object_id
INNER JOIN
sys.types AS types ON parameter.system_type_id = types.system_type_id
AND parameter.user_type_id = types.user_type_id
WHERE
procedures.name = 'UsernameSP'
This returns a result set:
name name is_nullable
--------------------------------------
#Username nvarchar 1
#CreateDate datetime 1
I need this query for an Oracle database. How can I run this query in Oracle?
select argument_name,position, data_type
from user_arguments
where object_name = <your procedure>
order by position
That assumed you are logged in to the current schema where the procedure resides. I don't think oracle has an equivalent of "is_nullable"

How can I select this in Microsoft Query?

I have a stored procedure and a simple table.
I need to join this two object then allow user to see the result using Microsoft Query in Excel.
This is what I have. The Exec SP_Budget create global temp table and fill ##tmpBudget
exec SP_Budget;
Select g.name, g.address,g.Amount,b.BudgetAmt from gTable g
Left join ##tmpBudget b on b.NameID=g.NameID
Microsoft query can only do a simple
select * from tTable
how can I do this?
I have to have the stored procedure because it does UNpivot inside the SP_Budget
EDIT:
The more I think about this. I think I need to post the original SP_Budget
so here it is. Because maybe a better approach is to create a function rather than SP_Budget. Here is my SP_Budget. Is it possible to convert this SP to a function?
--this link show me how to build column list for the PIVOT/UNPIVOT http://stackoverflow.com/questions/9585094/sql-server-pivots-displaying-row-values-to-column-headers
--this link show me how to build column list of a specific table http://stackoverflow.com/questions/18775409/unpivot-with-dynamic-columns-plus-column-names
--here we build the dynamic query for the column list for the PIVOT/UNPIVOT
declare #sql AS NVARCHAR(MAX);
declare #cols nvarchar(max);
select #cols = coalesce(#cols+N',', N'') + quotename(c.name) from syscolumns c
inner join sysobjects o on c.id = o.id and o.xtype = 'u'
where o.name = 'AcctHist' and c.name not in ('PID', 'UID') and c.name like 'ptdbal%' and c.name <> 'PtdBal12' order by c.colid
--Construct the full T-SQL statement
--and execute dynamically
SET #sql = N'select
DB,Acct,Sub,cpnyid
,Fiscyr+
CASE WHEN len(Convert(varchar(2),CONVERT(int,right(Period,2))+1))=1
THEN ''0''+Convert(varchar(2),CONVERT(int,right(Period,2))+1)
ELSE Convert(varchar(2),CONVERT(int,right(Period,2))+1)
END "Period"
,Amounts
from (
SELECT A.DB,A.Sub,A.acct,A.FiscYr,A.CpnyID
, sum(A.PtdBal00) "PtdBal00"
,sum(A.PtdBal01) "PtdBal01"
,sum(A.PtdBal02) "PtdBal02"
,sum(A.PtdBal03) "PtdBal03"
,sum(A.PtdBal04) "PtdBal04"
,sum(A.PtdBal05) "PtdBal05"
,sum(A.PtdBal06) "PtdBal06"
,sum(A.PtdBal07) "PtdBal07"
,sum(A.PtdBal08) "PtdBal08"
,sum(A.PtdBal09) "PtdBal09"
,sum(A.PtdBal10) "PtdBal10"
,sum(A.PtdBal11) "PtdBal11"
FROM vz_Finance_Budget A
Group by A.DB,A.Sub,A.acct,A.FiscYr,A.CpnyID
)xx
UNPIVOT (Amounts for Period in ('+#cols+')) unpiv;';
EXEC sp_executesql #sql;
Edit2:
Thank you for all the suggestions. I decided that the limiting factor is microsoft query itself. Plus microsoft query should be replaced with something newer (I think). Instead of configuring my server to allow openrowset or OPENQuery. I will look into microsoft query replacement.
not sure if this is the right way to go. but I will update here. thanks.
Edit3: Trying this blog now: http://blogs.office.com/2010/06/07/running-a-sql-stored-procedure-from-excel-no-vba/ I will update when I complete it
As far as I know you can have explicit JOIN in Microsoft Query
Description of the usage of joins in Microsoft Query
SELECT ....
FROM tbl1, tbl2
WHERE tbl1.Id = tbl2.Id
Update
If you want to have the result set in Excel, You can use OPENROWSET to export the data from SQL Server to Excel.
INSERT INTO OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;Database=C:\testing.xls;',
'SELECT name, address, Amount, BudgetAmt FROM [Sheet1$]')
SELECT g.name, g.address, g.Amount, b.BudgetAmt FROM gTable g
LEFT JOIN #tmpBudget b ON b.NameID = g.NameID
As you just mentioned earlier, you need to save your proc result into a temp table first
sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO
SELECT * INTO #tmpBudget
FROM OPENROWSET('SQLNCLI'
,'Server=(local)\SQL2008;Trusted_Connection=yes;'
,'EXEC SP_Budget')
I solved this using this blog below
http://blogs.office.com/2010/06/07/running-a-sql-stored-procedure-from-excel-no-vba/
basically in excel, when you click data tab - From other sources - instead of "from microsoft query". I select "from SQL server". With "from SQL Server". I have the option in the "Connection properties - definition" to select the command type to SQL (instead of table)
the blog explains this with screenshot... Thanks

How to determine the SQL Server object name from object id and database id?

I need the behaviour of SQL Server 2005 where function OBJECT_NAME takes two arguments, obj id and db id, while SQL Server 2000 takes only obj id so the execution must be in the context of the database to which inspected object belongs to.
Solution must be possible to implement in a function, so it can be used in a select query.
In SQL 2005 and up it is of course trivial to do this. The problem is SQL 2000. I used 2000 a lot back when, but no longer have access to any installations of it; the rest of this is largely from memory, and may be inaccurate.
The key thing is how to retrieve data from a database other than the "current" database, when you cannot know what that other database (or databases) will be at the time the code is written. (Yes, the db_id parameter is very convenient!) For this problem and for similar problems, the general work-around is to create dynamic code, something like:
SET #Command = 'select name from ' + #dbname + '.dbo.sysobjects where object_id = ' + #ObjectId
EXECUTE (#Command)
The problem is, I'm pretty sure you can't run dynamic code within functions (or perhaps just within SQL 2000 functions).
You might have to resort to creating a temp table, populating it via dynamic query, and then using it within the "main" query you are trying to write. Psuedo code would be like:
CREATE #TempTable
IF SQL2000 or earlier
INSERT #TempTable EXECUTE (select data from TargetDb.dbo.sysobjects)
-- Note that the entire insert may need to be in the dynamic statement
ELSE
INSERT #TempTable SELECT [from query based on object_id]
SELECT [the data you need]
from YourTable
join #TempTable
In SQL 2008 and up, use:
OBJECT_NAME ( object_id [, database_id ] )
for example:
SELECT TOP 10
object_schema_name(objectid, dbid) as [SchemaName],
object_name(objectid, dbid) as [ObjectName],
e.*
from sys.dm_exec_cached_plans P
CROSS APPLY sys.dm_exec_query_plan(P.plan_handle) E

Resources