List all stored procedures with schema name - sql-server-2008

Can anyone advise on a way to list all stored procedures along with their schema names in a database? Thanks!

SELECT [schema] = OBJECT_SCHEMA_NAME([object_id]),
name
FROM sys.procedures;
or
SELECT [schema] = SCHEMA_NAME([schema_id]),
name
FROM sys.procedures;
For a specific database, you can just change the context to that database first, or change Marc's query slightly (my queries are no good in this case because they rely on functions that are context-sensitive):
SELECT
SchemaName = s.name,
ProcedureName = pr.name
FROM
databasename.sys.procedures pr
INNER JOIN
databasename.sys.schemas s ON pr.schema_id = s.schema_id;
If you want to do this for all databases:
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql += N'
UNION ALL SELECT db = N''' + name + ''',
s.name COLLATE Latin1_General_CI_AI,
o.name COLLATE Latin1_General_CI_AI
FROM ' + QUOTENAME(name) + '.sys.procedures AS o
INNER JOIN ' + QUOTENAME(name) + '.sys.schemas AS s
ON o.[schema_id] = s.[schema_id]'
FROM sys.databases
-- WHERE ... -- probably don't need system databases at least
SELECT #sql = STUFF(#sql, 1, 18, '')
-- you may have to adjust ^^ 18 due to copy/paste, cr/lf, tabs etc
+ ' ORDER BY by db, s.name, o.name';
EXEC sp_executesql #sql;
The collate clauses are necessary in case you have databases with different collations.

Try this:
SELECT
SchemaName = s.name,
ProcedureName = pr.name
FROM
sys.procedures pr
INNER JOIN
sys.schemas s ON pr.schema_id = s.schema_id
This should list all stored procedures and their schema name as a result set.
Both views - sys.procedures and sys.schemas - have quite a few more attributes - check them out, if you need them, include them in your query.

If you want to search for procs with required schema name you can use this query:
SELECT
SchemaName = s.name,
ProcedureName = pr.name
FROM
sys.procedures pr
INNER JOIN
sys.schemas s
ON pr.schema_id = s.schema_id
WHERE s.name = 'YOUR_SCHEMA_NAME'
ORDER BY SchemaName;

this may help You..
SELECT * FROM sys.procedures;

You can use Script Generator to get them. In the left pan right click on the database for which you want to get Stored Procedures, Tasks->Generate Scripts Click Next and choose Select Specific Database Objects and select Stored Procedures and click on next, there you can customize as you need and generate the scripts.

Try this:
execute [sys].[sp_stored_procedures]
Or try this and also get all parameters:
execute [sys].[sp_sproc_columns]
Ok...you'll have to loop through all DB catalog names with this, but...

SELECT name,crdate FROM dbo.sysobjects WHERE (type = 'P') order by name
SELECT [schema] = OBJECT_SCHEMA_NAME([object_id]),name FROM sys.procedures;
select OBJECT_SCHEMA_NAME([object_id]) as 'SchemaName',name as 'SP Name ' ,
create_date,modify_date FROM sys.procedures order by OBJECT_SCHEMA_NAME([object_id]), name

Related

Finding duplicate values over multiple databases in MySQL

There are multiple (mysql) databases running under 1 website. 1 database per registered account.
I'm looking for duplicate records in each contacts-table.
This is what i have for finding duplicates inside only 1 database:
SELECT COUNT(contacts.email), contacts.email, contacts.state, contacts.source,
FROM shard_40000006.contacts
LEFT JOIN shard_40000006.optin ON optin.email=contacts.email
GROUP BY contacts.email
HAVING COUNT(contacts.email) > 1;
The query i need searches for duplicates over shard_40000001, shard_40000002, shard_40000003, .. shard_40999999
You can use dynamic tsql.
declare #sqltext nvarchar(max) = N''
declare #parameter varchar(max) = 'define what you want to search here'
select #sqltext += '
SELECT COUNT(contacts.email), contacts.email, contacts.state, contacts.source,
FROM '+name+'.dbo.contacts
LEFT JOIN '+name+'.dbo.optin ON optin.email=contacts.email
GROUP BY contacts.email
HAVING COUNT(contacts.email) > 1'
FROM sys.databases
WHERE OBJECT_ID(QUOTENAME(name) + '.dbo.prac_nag', 'U') IS NOT NULL -- will return only if the table exists
print #sqltext
-- once your review the output, uncomment out below
--exec sp_executesql #sqltext
I just put refernce code. i didn't test this code.

How to use query string inside IN statement in MySQL stored procedure

friends I have a stored procedure. which taking an input. But the input is a Query string. When I'm executing that string in IN statement I'm not getting anything.
My Stored Procedure is:
CREATE DEFINER=`root`#`localhost` PROCEDURE `SampleProcedure`(IN category VARCHAR(255)
IN location VARCHAR(255),
IN classification VARCHAR(255))
BEGIN
SELECT u1.firstname , u1.lastname, u1.avatar , s1.address ,c1.cityName
FROM user u1,serviceprovider s1, city c1
WHERE s1.userId=u1.id
AND c1.cityId=s1.city
AND s1.serviceProviderId
IN
(SELECT DISTINCT serviceprovider_cl AS serviceProviderId FROM db.serviceprovider_classification t1
INNER JOIN
db.locationid t2 ON t1.serviceprovider_cl=t2.serviceprovider_locationId
INNER JOIN
db.serviceprovider_category t3 ON t2.serviceprovider_location
INNER JOIN
db.serviceprovider_category t3 ON t2.serviceprovider_locationId=t3.serviceprovider_category
WHERE
t1.serviceproviderclassification_classification IN (classification)
AND
t2.location_serviceLocation IN (location)
AND
t3.category_serviceProviderCategory IN (category)
);
END
In category, classification and location. I'm getting another query in String. So to execute that string or How to convert it into query or how to use string as Query?
Thanks
for this you can use something called Prepared Statements, you can find more about that here...
So here is an SQL Fiddle where you can see how prepared statement works...
As you can see in this simple stored procedure it is not complicated that much. Basically there is three step to do this.
First create string which will be used in prepared statement. You do this to connect your query and query you will get as a string (IN category VARCHAR(255)) into one statement.
In my Fiddle:
SET #myString =
CONCAT('SELECT * FROM t2 WHERE t1_id IN (', category, ')');
That is the hardest part. Than you should perapare statement from that string
PREPARE statement FROM #myString;
End than execute the statement
EXECUTE statement;
When you call your procedure you pass your string which will be part of statement:
CALL SimpleProcedure('SELECT id FROM t1 WHERE val1 = "myVal2"');
And that's the logic you should apply on your problem.
That should look like this:
CREATE DEFINER=`root`#`localhost` PROCEDURE `SampleProcedure`(IN category VARCHAR(255))
BEGIN
SET #myString =
CONCAT('SELECT u1.firstname , u1.lastname, u1.avatar , s1.address ,c1.cityName
FROM user u1,serviceprovider s1, city c1
WHERE s1.userId=u1.id
AND c1.cityId=s1.city
AND s1.serviceProviderId
IN
(', category,
' INNER JOIN
db.serviceprovider_category t3 ON t2.serviceprovider_locationId=t3.serviceprovider_category
WHERE
t3.category_serviceProviderCategory IN (', category, '))');
PREPARE statement FROM #myString;
EXECUTE statement;
END
EDIT: note that between ' and INNER JOIN there is one blank space because CONCAT, without that, would connect last word from 'category' query and inner join and that will cause you problem and your query wont work!
GL!
P.S. Also i notice that you mix both syntax when JOIN table (old comma separated JOIN and the new way) which is not look nice, it would be good to correct that and use new INNER JOIN syntax like you do in your sub query...
New EDIT (based on question edit)
CREATE DEFINER=`root`#`localhost` PROCEDURE `SampleProcedure`(IN category VARCHAR(255)
IN location VARCHAR(255),
IN classification VARCHAR(255))
BEGIN
SET #myString =
CONCAT('SELECT u1.firstname , u1.lastname, u1.avatar , s1.address ,c1.cityName
FROM user u1,serviceprovider s1, city c1
WHERE s1.userId=u1.id
AND c1.cityId=s1.city
AND s1.serviceProviderId
IN
(SELECT DISTINCT serviceprovider_cl AS serviceProviderId FROM db.serviceprovider_classification t1
INNER JOIN
db.locationid t2 ON t1.serviceprovider_cl=t2.serviceprovider_locationId
INNER JOIN
db.serviceprovider_category t3 ON t2.serviceprovider_location
INNER JOIN
db.serviceprovider_category t3 ON t2.serviceprovider_locationId=t3.serviceprovider_category
WHERE
t1.serviceproviderclassification_classification IN (', classification, ')
AND
t2.location_serviceLocation IN (', location, ')
AND
t3.category_serviceProviderCategory IN (', category, '))');
PREPARE statement FROM #myString;
EXECUTE statement;
END
Subquery in IN statement is equal to JOIN with subquery's table. Why you need "exotic" syntax instead of simple join.

Creating a self-reflexive cross join

Hi I'm looking to see if there is alternative syntax for the following self-reflexive cross-join. The objective is a sort of row-filler for a table - dates should have entries for every cdn. I am using MySQL
select
d.labelDate,
n.cdn,
networks.sites
from (
select
distinct labelDate
from
cdn_trend
) as d
cross join (
select
distinct cdn
from cdn_trend
) as n
left join cdn_trend as networks
on networks.labelDate = d.labelDate
and networks.cdn = n.cdn
order by
labelDate,
cdn
I've tried recasting the cross-join using simple aliases but that gives me column errors in the join. Is it possible to do so or should I consider using views instead?
As a cross join should simply return the Cartesian product of two tables it should be the same as simply selecting both without a join. However, the following raises an "unknown column d.labelDate in on clause" exception
select distinct d.labelDate, n.cdn, networks.sites
from
cdn_trend as d,
cdn_trend as n
left join cdn_trend as networks ON
(n.labelDate = networks.labelDate
and d.cdn = networks.cdn)
order by labelDate, cdn
Error Code: 1054. Unknown column 'd.cdn' in 'on clause'
Because the length of dand n are relatively small the size of the query is fast enough.
I think you were close in your original intent... For every date, you want the results of every network node status. If you list multiple tables in the WHERE clause without a join condition, it by default will create a Cartesian... From that, join to your detail table...
select
d.labelDate,
n.cdn,
networks.sites
from
( select d.LabelDate, n.cdn
from
( select distinct labelDate
from cdn_trend ) as d,
( select distinct cdn
from cdn_trend ) as n ) as CrossResults
LEFT JOIN cdn_trend as networks
on CrossResults.labelDate = networks.labelDate
and CrossResults.cdn = networks.cdn
order by
networks.labelDate,
networks.cdn
Reading the comments and the extra info you need a pivot with y - lableDate and x - cdn and values - sites assuming the values for cdn are (a,b,c) and that sites is a number you can try this:
SELECT
labelDate,
SUM(IF(cdn = 'a',sites,0)) as cdn_a,
SUM(IF(cdn = 'b',sites,0)) as cdn_b,
SUM(IF(cdn = 'c',sites,0)) as cdn_c
FROM
cdn_trend
GROUP BY
labelDate
And the output should be something like this (i used the sample data from you) :
labelDate cdn_a cdn_b cdn_c
2013-04 NULL 5 4
2013-05 6 NULL NULL
....
After some playing around this is the best I could come up with. It seems that parametrising the table name would be possible but would involve yet another layer of statement generation that I fortunately don't need for this project.
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER="root"#"localhost" PROCEDURE "cdn_pivot"(
IN slice varchar(64),
IN start date,
IN stop date)
BEGIN
SET ##group_concat_max_len = 32000;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
' sum(IF(cdn = ''',
cdn,
''', sites,NULL)) "'
,cdn, '"'
)
) INTO #sql
FROM cdns ORDER BY sites;
SET #stmt = CONCAT('SELECT labelDate, ',
#sql,
' from cdns
WHERE slice = ''',
slice,
''' AND ( labelDate between''',
start,
''' AND ''',
stop,
'''
)
GROUP BY labelDate');
prepare stmt from #stmt;
execute stmt;
deallocate prepare stmt;
SET ##group_concat_max_len = 1024;
END
This can then simply be called e.,g.
call cdn_pivot('Top100', '2013-01-01', 2013-02-01')
Given the problems associated with testing this code and keeping it with any client-side code it's very tempting to generate the dynamic part of the head on the client and, at least for this kind of use case, the performance penalty of the additional query shouldn't be too high. The key thing is obviously understanding how to generate the columns dynamically.

"Looping" through databases with sp_MSforeachdb and returning 1 data set

So, I've been wrestling with the code I found on my buddy's website:
8 Steps to Moving Database Logins
I want to generate the Database Level Security, Roles, and Explicit Permissions statements in one output so I'm not copying and pasting over and over again and so that they run for all databases on the server (minus tempdb of course).
Declare #FullStatement varchar(MAX)
Set #FullStatement = ' use [?]; SELECT dp.state_desc + N'' '' + dp.permission_name + N'' TO '' + cast(QUOTENAME(dpl.name COLLATE DATABASE_DEFAULT) as nvarchar(500)) AS TSQLScript
FROM sys.database_permissions AS dp
INNER JOIN sys.database_principals AS dpl ON (dp.grantee_principal_id = dpl.principal_id)
WHERE dp.major_id = 0
and dpl.name not like ''##%'' -- excluds PBM accounts
and dpl.name not in (''dbo'', ''sa'', ''public'')
ORDER BY dp.permission_name ASC, dp.state_desc ASC'
Exec sp_MSforeachdb #FullStatement
How can I modify what I have, which works as is but is inconvenient, using a Table Variable, Temp Table, etc so all of the statements are in one data set?
David,
Is this what you want?
CREATE TABLE tempdb.dbo.Results (c1 VARCHAR(8000))
Declare #FullStatement varchar(MAX)
Set #FullStatement = 'SELECT ''use [?]''; SELECT dp.state_desc + N'' '' + dp.permission_name + N'' TO '' + cast(QUOTENAME(dpl.name COLLATE DATABASE_DEFAULT) as nvarchar(500)) AS TSQLScript
FROM [?].sys.database_permissions AS dp
INNER JOIN [?].sys.database_principals AS dpl ON (dp.grantee_principal_id = dpl.principal_id)
WHERE dp.major_id = 0
and dpl.name not like ''##%'' -- excluds PBM accounts
and dpl.name not in (''dbo'', ''sa'', ''public'')
ORDER BY dp.permission_name ASC, dp.state_desc ASC'
INSERT INTO tempdb.dbo.Results Exec sp_MSforeachdb #FullStatement
select * FROM tempdb.dbo.Results
There are multiple ways to get this done. You can use powershell to loop through all databases and put the results in excel. Mr Nelson has this on his powershell sql university series. Sorry, would pull the link for you but i am typing on my phone at the airport.
Why are you scripting database users and permissions? They are in the database and will still be there when you migrate the databases. You don't need to do that unless you're recreating the databases from scratch.

Dropping all View under particular schema - SQL

How to drop all views under particular schema.
Ex: if I got below views in db.
[dbo].[view1]
[dbo].[veiw2]
[dbo].[view3]
[myView].[view1]
[myView].[veiw2]
[myView].[view3]
I just want to drop all views under schema myView all at a time.
Try this:
select 'drop view ' + QUOTENAME(sc.name) + '.' + QUOTENAME(obj.name) + ';'
from sys.objects obj
INNER JOIN sys.schemas sc
ON sc.schema_id = obj.schema_id
where obj.type='V'
and sc.name = 'myView';
I have tons of views (so, just aggregate drop query to one nvarchar(max) doesnt work - the query is truncated.) and i want to except some of views from deletion.
In this example, i want to drop every view from every schema beginnig with usr_* but not usr_test, usr_usr, usr_usr1, usr_usr2 and usr_usr3.
cursor is used because i dont care about few ms. This view cleaning query is used before integration tests, its not really speed-critical (and yet it perform really well)
declare drop_view_cursor cursor for
select 'drop view ' + QUOTENAME(sys.schemas.name) + '.' + QUOTENAME(sys.views.name) + ';'
from sys.views
inner join sys.schemas on sys.schemas.schema_id = sys.views.schema_id
where sys.schemas.schema_id in
(
select s.schema_id
from sys.schemas as s
where s.name like 'usr_%'
and s.name not in ('usr_test', 'usr_usr', 'usr_usr1', 'usr_usr2', 'usr_usr3')
)
declare #sql nvarchar(max)
open drop_view_cursor
fetch next from drop_view_cursor into #sql
while ##FETCH_STATUS = 0
begin
exec (#sql)
fetch next from drop_view_cursor into #sql
end
close drop_view_cursor
deallocate drop_view_cursor
This takes into account Schema, uses the system tables, and outputs to a variable that may then be executed. This way you don't have the problem of your Select truncating your script, because the Select and Print statements are limited on the length of what they may return.
The following runs in SQL Server 2008:
DECLARE #DropViewCommand nVarChar(MAX) = ''
SELECT #DropViewCommand = #DropViewCommand
+ 'DROP VIEW '+ QUOTENAME(S.Name) + '.' + QUOTENAME(V.name) + '; '
FROM sys.views as V
JOIN sys.schemas as S
ON S.schema_id = V.schema_id
WHERE S.name = 'dbo'--Selectively delete by Schema. Comment out to delete all views.
PRINT #DropViewCommand--See the command used in dropping all views (will be truncated in Select/Print, but not when Executing).
EXEC (#DropViewCommand)
Re-posting answer for those looking for specific solution. Put DROP view code in WHILE loop as shown below:
DECLARE #name VARCHAR(128)
DECLARE #SQL VARCHAR(254)
DECLARE #schema VARCHAR(128)
SELECT #name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'V' AND category = 0 ORDER BY [name])
SELECT #schema = (SELECT TOP 1 schema_name(schema_id) FROM sys.views WHERE [name] = #name)
WHILE #name IS NOT NULL
BEGIN
SELECT #SQL = 'DROP VIEW [' + #schema + '].[' + RTRIM(#name) +']'
EXEC (#SQL)
PRINT 'Dropped View: ' + #name
SELECT #name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'V' AND category = 0 AND [name] > #name ORDER BY [name])
SELECT #schema = (SELECT TOP 1 schema_name(schema_id) FROM sys.views WHERE [name] = #name)
END
GO